juqery模板 Templates

如今已經有了許多JavaScript的解決方案模板,從這方面說,標準化的模板解決方案必然是大勢所趨。在本節中,咱們向你簡要描述四個最流行最有趣的模板。現有的模板解決方案能解決什麼?那些特點在jQuery核心中有意義。javascript

微模板css

John Resig的微型模板引擎很是小(未壓縮僅2KB)。然而,這點小小的代碼已經抓到了渲染一個模板的核心功能。html

下面是一個用微模板引擎顯示單個JavaScript產品對象的例子。java

<script src="../jquery-1.4.1.js" type="text/javascript">>;/script>;
<script src="MicroTemplating.js" type="text/javascript">;</script>;
<script type="text/javascript">;
    var product = { name: "Laptop", price: 788.67 };
    $(showProduct);
    function showProduct() {
        $("#results").html( tmpl("productTemplate", product) );
    }
    function formatPrice(price) {
        return "$" + price;
    }
</script>;jquery

tmpl()方法用來從一個product模板和product對象生成一個字符串。其結果分配給一個名叫results的div元素的innerHTML。web

product模板在頁面body的SCRIPT中定義。數據庫

<script type="text/html" id="productTemplate">
    Product Name: <%= name %>
    <br />
    Product Price: <%= formatPrice(price) %> 
</script>
<div id="results"></div>express

注意,SCRIPT的type屬性爲「text/ html」。用這種方式來聲明web瀏覽器會忽略SCRIPT裏的內容,將其內容看成字符串來對待。數組

注意,模板包含表明產品名稱和價格屬性的表達式。調用JavaScript的formatPrice()方法來格式化產品的價格。在模板裏你能夠調用任何JavaScript函數。瀏覽器

這裏是如何渲染一個product對象數組的示例:

function showProducts() { 
    // parse the template 
    var template = tmpl("productTemplate"); 
    // loop through the products 
    var results = ''; 
    for (var i = 0; i < products.length; i++) { 
        results += template(products[i]); 
    } 
    // show the results 
    $("#results").html(results); 
}

tmpl()函數支持currying(關於什麼currying,能夠在網上查閱資料)。若是沒有提供數據給tmpl()函數,他將返回一個javascript函數,表明解析的模板。

在上面的代碼中,模板被解析,而後爲每個product調用模板方法生成一個字符串。最後,字符串分配給名叫results的div元素的innerHTML。
jTemplates

jTemplates是一個功能豐富的模板引擎,它做爲一個jQuery插件來執行。jTemplates支持不少先進的功能,包括:

外部模板--您能夠經過提供的URL從外部文件加載模板,外部文件能夠包含多個模板; 
外部數據--您能夠從外部URL加載數據; 
實時刷新--你能夠自動按期的更新模板內容; 
HTML編碼--你能夠阻止諸如<和>的編碼字符對JavaScript插入的攻擊; 
Includes--您能夠在一個模板中包含另外一個模板; 
調試模式--您能夠在出錯的地方終止模板引擎,並顯示錯誤信息。 
下面示例中的代碼演示瞭如何使用jTemplates顯示產品清單。

<script src="../jquery-1.4.1.js" type="text/javascript"></script>
<script src="jquery-jtemplates_uncompressed.js" type="text/javascript"></script>
<script type="text/javascript">
    var data = { 
        products: [
            { name: "Laptop", price: 788.67 },
            { name: "Comb", price: 2.50 },
            { name: "Pencil", price: 1.99 }
        ]};
    $(showProducts);
    function showProducts() {
        // attach the template
        $("#results").setTemplateElement("template");
        // process the template
        $("#results").processTemplate(data);
    }
    function formatPrice(price) {
        return "$" + price;
    }
</script>

setTemplateElement()方法給HTML元素指定一個模板,processTemplate()方法使用所提供的數據處理模板。

上面的代碼中,加載的模板爲名爲textarea的元素,下面就是模板在頁面主體中呈現的外觀。

<textarea id="template" style="display:none">
    {#foreach $T.products as product}
    <div>
        Product Name: {$T.product.name}
        <br />
        Product Price: {formatPrice($T.product.price)} 
    </div>
    {#/for}
</textarea>

注意,一個jTemplate模板能夠包含諸如#foreach、#for、and #if的特殊命令。至於調用formatPrice()函數,它代表模板也能夠包含任意JavaScript函數的調用。

默認狀況下,爲了防止JavaScript的插入攻擊,在傳遞給模板的數據中,jTemplate 的HTML編碼了包含的特殊字符。例如,若是一個產品的名稱爲<b>Laptop<b>,那麼,名稱將被轉換成&lt;b&gt;Laptop&lt;/b&gt; 。

jTemplates使您能夠同時從外部URL加載模板和數據。例如,下面的代碼將從一個名爲MyTemplates.htm的文件中加在模板,從一個名爲MyData.htm文件中加在一系列數據。

function showProducts() { 
    $.jTemplatesDebugMode(true); 
    // attach the template 
    $("#results").setTemplateURL("MyTemplate.htm"); 
    // process the template 
    $("#results").processTemplateURL("MyData.htm"); 
}

MyTemplate.htm文件以下所示:

{#foreach $T.products as product} 
    Product Name: {$T.product.name} 
    Product Price: {formatPrice($T.product.price)}  
{#/for}

jTemplates容許您能夠在一個單一文件定義多個模板,雖然在MyTemplate.htm文件沒有演示此功能。

最後,MyData.htm文件以下所示:

{"products": [ 
  { "name": "Laptop", "price": "788.67" }, 
  { "name": "Comb", "price": 2.50 }, 
  { "name": "Pencil", "price": 1.99 } 
] }

固然,包含在MyData.htm的內容有數據庫動態生成。

PURE(純粹分離式渲染引擎)

PURE 模板引擎的目的在於使開發人員不使用任何特殊標記來聲明模板。使用PURE有兩種方法:autoRender()方法或render()方法。

使用autoRender()方法時,PURE自動將JSON的屬性名稱映射到css的class上。例如,你能夠編寫下面的代碼來顯示單個產品。

$(showProduct); 
function showProduct() { 
    var product = { name: "Laptop", price: 788.67 }; 
    $('div.product').autoRender(product); 
}

autoRender()經過將product的name和price 屬性分別映射到class爲name和price 的元素上來顯示產品。

<div class="product"> 
    Product Name: <span class="name"></span> 
    <br /> 
    Product Price: <span class="price"></span>         
</div>

請注意,模板中沒有特殊字符,PURE用純粹的HTML完成一切。

autoRender()方法依賴於JSON的屬性名映射到class名的協議,若是你不想依賴於該協議,你能夠用render()方法來代替。

function showProduct() { 
    var product = { name: "Laptop", price: 788.67 }; 
    var directives = { 'span#name' : 'name', 'span#price': 'price'}; 
    $('div.product').render(product, directives); 
}

請注意,一系列指令和要顯示的項目傳遞給render()。這些選擇器將選擇器映射到JSON屬性名,第一個指令將Id爲name的span元素映射到name屬性,第二個指令將Id爲price的span元素映射到price屬性。下面是HTML:

<div class="product"> 
    Product Name: <span id="name"></span> 
    <br /> 
    Product Price: <span id="price"></span>         
</div>

PURE也能夠用來渲染一個JavaScript對象數組。例如,下面的代碼渲染一個product數組。

function showProducts() { 
    var data = { "products": [ 
            { name: "Laptop", price: 788.67 }, 
            { name: "Comb", price: 2.50 }, 
            { name: "Pencil", price: 1.99 } 
        ]}; 
    $('#productTemplate').autoRender(data); 
}

因爲數組名爲product,PURE將每個product映射到class爲product的元素上,如下模板顯示全部的三個product。

<div id="productTemplate"> 
<div class="products"> 
    Product Name: <span class="name"></span> 
    <br /> 
    Product Price: <span class="price"></span>         
</div> 
</div> 
ASP.NET Ajax 模板

在 ASP.NET的Ajax庫支持客戶端模板。這個庫支持不少先進的功能:

僞變量--你能夠在模板中用一組諸如表明模板實例當前索引的$index特別變量; 
動態模板-- 在渲染JavaScript對象數組時,你能夠動態的改變模板; 
動態佔位--在渲染JavaScript對象數組時,你能夠動態的更改模板的佔位符。 
例如,您可使用下面的代碼在模板中渲染產品列表:

var products = [
    { name: "Laptop", price: 788.67 },
    { name: "Comb", price: 2.50 },
    { name: "Pencil", price: 1.99 }            
];
Sys.require([Sys.components.dataView], function () {
    $("#products").dataView(
    {
        data: products
    });
});

DataView()方法用來在一個模板中顯示系列產品。模板包含在名爲product的div元素中。

<div id="products" class="sys-template"> <div id="{{ $id('product') }}"> Product Name: {{ name }} <br /> Product Price: {{ formatPrice(price) }} </div> </div>

請注意,ASP.NET Ajax模板只是一個dom元素。由於模板僅僅是一個DOM元素,模板就不須要包裹在SCRIPT或TEXTARE或HTML註釋中。在這種狀況下,一個DIV元素爲每個產品建立一個新實例。

此外,請注意$id()僞變量。$id()解決模板和元素id的有關問題。若是你爲一個模板添加一個帶有id的元素,模板用來收集選項,結果是將出現重複id。$id()僞變量爲每個模板實例生成惟一的ids,使你避免了這個問題。

ASP.NET Ajax還支持一種所謂的動態模板。想一想如下,你已經爲每個新產品建立了一個模板,一般的產品模板看起來是這樣的:

<!-- New template --> 
<div id="newTemplate" class="sys-template"> 
    <div> 
        <img src="new.gif" /> 
        Product Name: {{ name }} 
        <br /> 
        Product Price: {{ formatPrice(price) }}  
    </div> 
</div> 
<!-- Normal template --> 
<div id="normalTemplate" class="sys-template"> 
    <div> 
        Product Name: {{ name }} 
        <br /> 
        Product Price: {{ formatPrice(price) }}  
    </div> 
</div>
 

這兩個模板實際上是同樣的,除非新的模板顯示一個新的圖像。

你能夠在每個模板顯示以前建立一個itemRendering事件處理程序。在該程序中,你能夠指定用來顯示數據項的模板。

function itemRendering(dataView, args) { 
    // Get the current data item 
    var product = args.get_dataItem(); 
    // Set the template dynamically 
    if (product.dateCreated.getFullYear() == 2010) { 
        args.set_itemTemplate("#newTemplate"); 
    } else { 
        args.set_itemTemplate("#normalTemplate"); 
    } 
}
 

上面的代碼使用兩個模板中的一個來顯示產品。若是產品是新的(建立於2010年)用newTemplate來顯示,不然用normalTemplate模板。

ASP.NET Ajax還支持一種所謂的動態佔位。動態佔位使你能夠在文檔的不用位置顯示不一樣項。例如,你可能但願你全部的新產品在你文檔中的「新產品」區域顯示:

<h1>New Products</h1> 
<div id="newPlaceholder"></div> 
 
<h1>All Products</h1> 
<div id="normalTemplate" class="sys-template"> 
    <div> 
        Product Name: {{ name }} 
        <br /> 
        Product Price: {{ formatPrice(price) }}  
    </div> 
</div>

請注意名爲newPlaceholder的div元素。你但願全部新產品都出如今這裏。

這裏是你如何編寫itemRendering處理程序在新的佔位符中放置新產品--建立於2010的產品。

function itemRendering(dataView, args) { 
    // Get the current data item 
    var product = args.get_dataItem(); 
    // Set the template dynamically 
    if (product.dateCreated.getFullYear() == 2010) { 
        args.set_itemPlaceholder("#newPlaceholder"); 
    }  
}
 

在jQuery core中增長模板支持
這部分包含一個提案--給jQuery核心中添加一個聲明和渲染模板的標準方法。這節包括模板API、示例代碼和討論要點。

API
jQuery.fn.render
經過給單個的數據項或一組數據項應用一個模板來生成DOM元素。

jQuery("#template") 
   .render(arrayOrObject, options) 
   .appendTo("selector");

參數

 

參數 類型 描述 
data 任何數據對象 任何數據對象 若是是數組,爲每一項實例化化一次。不然,該模板僅實例化一次 
options 對象 對象的字面意義表明可選設置。你能夠設置一個渲染和渲染的事件處理程序。你能夠傳遞任何值,這些值將被傳入到模板中


示例

下面是一個使用render()方法的簡單例子。render()方法用來以列表的方式顯示系列產品的name和price。

<script type="text/javascript"> 
jQuery(function(){ 
  var products = [ 
        { name: "Product 1", price: 12.99}, 
        { name: "Product 2", price: 9.99}, 
        { name: "Product 3", price: 35.59} 
  ]; 
 
  $("#template") 
     .render(products)  
     .appendTo("ul"); 
}); 
</script> 
<script id="template" type="text/html"> 
 <li>{%= name %} - {%= price %}</li> 
</script>
<ul></ul>
 

執行上面的代碼獲得的是下面的無需列表。

產品1 - 12.99 
Product 2 – 9.99產品2 - 9.99 
Product 3 – 35.59產品3 - 35.59 
jQuery DOM操做
jQuery DOM操做方法支持聲明一個模板。例如,你可使用jQuery.fn.append方法:

jQuery("selector") 
   .append("#template", arrayOrObject, options);
 

參數

 

參數 類型 描述 
selector 字符串 表明模板選擇符的一個字符串 
data 任何數據對象 任何數據對象 若是是數組,爲每一項實例化化一次。不然,該模板僅實例化一次 
options 對象 對象的字面意義表明可選設置。你能夠設置一個渲染和渲染的事件處理程序。你能夠傳遞任何值,這些值將被傳入到模板中


示例

下面的代碼使用append()方法而不是render()方法在一個無需列表中顯示系列產品的name和price。

<script type="text/javascript"> 
jQuery(function(){ 
  var products = [ 
        { name: "Product 1", price: 12.99}, 
        { name: "Product 2", price: 9.99}, 
        { name: "Product 3", price: 35.59} 
  ]; 
  $("ul").append("#template", products); 
}); 
</script> 
<script id="template" type="text/html"> 
 <li>{%= name %} - {%= price %}</li> 
</script> 
<ul></ul>
 

jQuery.templates
你能夠指定一個或多個編譯的模板給Query.templates對象設置。當你想給模板一個語義化的名字以便在一個文檔中很方便的屢次使用同一模板時,這頗有用。

用jQuery.tmpl()函數編譯一個模板

示例

<script type="text/javascript"> 
    // Assign compiled template 
    jQuery.templates.foo = jQuery.tmpl("<li>{%=name%}</li>"); 
    // use name foo as template in append() method: 
    jQuery("#container").append("foo", products); 
</script>
 

jQuery.tmplFn
在一個模板實例中,你可使用兩個內置的函數text()和html()渲染一個數據項。你能夠經過給jQuery.tmpFn對象指定一個新的函數在模板實例中擴展一組可用的函數。

下面的代碼向你演示瞭如何建立even()函數,該函數在輪替模板時返回true。在下面的示例中,even()函數用來在模板中交替呈現粗體行。

<script type="text/javascript"> 
    $(function() { 
        var products = [ 
            { name: "Product 1", price: 12.99 }, 
            { name: "Product 2", price: 9.99 }, 
            { name: "Product 3", price: 35.59 } 
        ];
        $.tmplFn.even = function() { 
            var context = jQuery._.context; 
            return (context.index % 2 === 0); 
        }; 
        $("div").append("#template", products); 
    }); 
</script> 
<script id="template" type="text/html"> 
  <div> 
  {% if (even()) { %} 
     <b> {%= name %} </b> 
  {% } else { %} 
     {%= name %}  
  {% }; %}  
  </div> 
</script> 
<div> 
</div>
模板語法
內嵌表達式
表達式能夠用{%= ... %} 的語法形式插入,這個分隔符最大限度的減小了編碼標記的機會,同時避免與現有的服務器端和客戶端的擴展標記相沖突(例如:{%=...%}可能與ASP和 ASP.NET相沖突)。

示例

簡單的數據插入:

<script type="text/html" id="tmp1"> 
    <li>{%= last %}, {%= first %}</li> 
</script>
 

表達式爲javascript,你能夠調用任何JavaScript函數用或使用更復雜的表達式。可是,注意,保持模板儘量的簡單是首選,後面要描述的兩個回調有助於理解這些。

<script type="text/html" id="tmp1"> 
    <li>{%= last + " " + first %}</li> 
</script>

HTML插入
默認狀況下,數據項在模板中被渲染時不會被HTML編碼。若是你在一個模板中顯示用戶提交的數據,那麼惡意用戶就可以執行跨站點腳本攻擊(XSS)。

注意下面代碼中第一個產品的名字,第一個產品包含一個沒有任何惡意的onClick事件處理程序,當數據項顯示,有人點擊了產品名字,JavaScript獲得執行。

<script type="text/javascript"> 
jQuery(function(){ 
  var products = [ 
        { name: "<a onclick='alert(\"do evil\")'>click here</a>", price: 12.99}, 
        { name: "Product 2", price: 9.99}, 
        { name: "Product 3", price: 35.59} 
  ]; 
  $("ul").append("#template", products); 
}); 
</script> 
<script id="template" type="text/html"> 
 <li>{%= name %} - {%= price %}</li> 
</script> 
<ul></ul>
 

爲了很容易的在一個模板中給要顯示的數據進行HTML編碼,使你免遭這種XSS的進攻,可使用一個名爲text()的內置函數。text()函數將一個數據項轉換成文本節點。這裏告訴你如何使用text()函數。

<script type="text/javascript"> 
jQuery(function(){ 
  var products = [ 
        { name: "<a onclick='alert(\"do evil\")'>click here</a>", price: 12.99}, 
        { name: "Product 2", price: 9.99}, 
        { name: "Product 3", price: 35.59} 
  ]; 
  $("ul").append("#template", products); 
}); 
</script> 
<script id="template" type="text/html"> 
 <li>{% text(name) %} - {%= price %}</li> 
</script> 
<ul></ul>
 

代碼塊
除了表達式,你能夠在模板中插入代碼執行自定義邏輯、條件或循環。代碼塊用{%....%}語法來分隔(沒有=)。

示例

這個例子顯示系列產品的name,若是有可用的「specials」則顯示。

<script type="text/html" id="tmp1"> 
<li> 
    {%= name %} 
    {% if (specials.length) { %} 
    <ul> 
    {% for (var i = 0, l = specials.length; i < l; i++) { %} 
        <li>{%= specials[i].details %}</li> 
    {% } %} 
    </ul> 
    {% } %} 
</li> 
</script>

上下文
在模板中,你可使用一個名叫$context 的特殊變量,這與提案後面要描述的rendering和rendered回調是同一個對象。$context具備如下屬性:

 

參數 描述  
data 傳遞給render()和append()函數的數組或對象 
dataItem 可是,這個放到with() 塊中,使得數據的每個字段能夠直接使用。例如,若是數據爲[{name:"dave"},{name:"bob"}] ,那麼{%= name } 就可使用。可是要注意,指向一個不存在的字段將是無效的。數據爲[{name:"dave"},{firstname:"bob"}] ,那麼第二個表達式「name」將無效。 
index 傳遞給模板的當前數據項在數組中的索引。若是是一個對象,索引爲0 
options 傳遞給模板的選項參數。這個提供了給模板傳遞額外參數的方法。


你對$context 變量的修改在模板中將保持一致。例如,你能夠在render()函數中給$context 變量添加計算字段。

function rendering(context) { 
  context.tax = context.dataItem.price * 0.23; 
}
 

你能夠在模板中使用tax計算字段,保持模板簡單,避免須要調試的內嵌表達式。

<script type="text/html" id="tmp1"> 
  The product with tax costs {%= $context.tax %} 
</script>
 

你可使用$context.options變量指向任何須要傳遞給render()和append()函數的選項。下面的示例演示瞭如何根據傳遞給append()函數的showSalePrice 參數值來顯示正常價格或零售價格。

<script type="text/javascript"> 
    jQuery(function() { 
        var products = [ 
            { name: "Product 1", price: 12.99, salePrice: 10.99 }, 
            { name: "Product 2", price: 9.99, salePrice: 7.99 }, 
            { name: "Product 3", price: 35.59, salePrice: 33.59 } 
        ]; 
        $("ul").append("#template", products, { showSalePrice: true });     
    }); 
</script> 
<script id="template" type="text/html"> 
 <li> 
     {%= name %} -  
     {%= $context.options.showSalePrice ? salePrice : price %} 
 </li> 
</script> 
<ul></ul>
 

注意如何在模板中根據$ context.options.showSalePrice屬性來顯示正常價格或零售價格。

模板渲染和呈現回調
你能夠利用傳遞給render()函數或append()的options參數來指定模板回調函數。有兩個回調函數:

rendering:該函數在模板渲染時當即調用。它做爲模板自身內同一$context對象的參數。回調返回flase以防渲染數據項。 
rendered:該函數在模板渲染時當即調用,可是在DOM元素已添加到文檔以前。 它一樣做爲模板自身內同一$context對象的參數。 
如下幾節討論使用rendering和rendered函數的幾種狀況:

執行復雜的計算
想象如下你要計算在模板中顯示的每一個product的稅率,但你又不想計算稅率的邏輯出如今模板自身中。此時,你能夠像這樣在rendering函數中執行稅率計算:

<script type="text/javascript"> 
    jQuery(function() { 
        var products = [ 
          { name: "Product 1", price: 12.99 }, 
          { name: "Product 2", price: 9.99 }, 
          { name: "Product 3", price: 35.59 } 
        ]; 
        $("ul").append("#template", products, { rendering: rendering }); 
       function rendering(context) { 
            var item = context.dataItem; 
            // setup additional information to be used more clearly within the template 
            // (avoids complex expressions) 
            item.tax = Math.floor(item.price * 8.75) / 100; 
        } 
    }); 
</script> 
<script id="template" type="text/html"> 
 <li>{%= name %} - price with tax {%= price + tax %} </li> 
</script> 
<ul></ul>
 

取消模板渲染
你能夠利用rendering()回調取消特定模板實例的渲染。下面的代碼演示瞭如何僅渲染標了刪除標記的產品。

<script type="text/javascript"> 
   jQuery(function() { 
        var products = [ 
            { name: "Product 1", price: 12.99 }, 
            { name: "Product 2", price: 9.99, deleted: true }, 
            { name: "Product 3", price: 35.59 } 
        ]; 
        $("ul").append("#template", products, { rendering: rendering }); 
        function rendering(context) { 
            if (context.dataItem.deleted) { 
                return false; 
            } 
        } 
    });
</script> 
<script id="template" type="text/html"> 
 <li>{%= name %} - {%= price %}</li> 
</script> 
<ul></ul>

當rendering()返回false時,模板不會顯示。在上面的示例代碼中,當產品標上刪除標記時,模板不會渲染。

嵌套模板
利用回調函數,你能夠建立其嵌套模板。例如,下面代碼顯示瞭如何顯示聯繫人名單,每一個聯繫人有一個或多個電話號碼。contactTemplate 用來顯示聯繫人名單,phoneTemplate 用來顯示每一個電話號碼。

<script type="text/javascript"> 
    $(function() {    
        var contacts = [ 
            { name: "Dave Reed", phones: ["209-989-8888", "209-800-9090"] }, 
            { name: "Stephen Walther", phones: ["206-999-8888"] }, 
            { name: "Boris Moore", phones: ["415-999-2545"] } 
        ]; 
        $("div").append("#contactTemplate", contacts, {rendered:rendered}); 
    }); 
    function rendered(context, dom) { 
        $("div.phones", dom) 
            .append("#phoneTemplate", context.dataItem.phones); 
    }  
</script> 
<script id="contactTemplate" type="text/html"> 
 <div> 
     {%= name %} 
     <div class="phones"></div> 
 </div> 
</script> 
<script id="phoneTemplate" type="text/html"> 
 <div> 
     Phone: {%= $context.dataItem %} 
 </div> 
</script> 
<div></div>
 

建立插件
假設你想在模板中使用插件--如jQuery UI Datepicker。此外,想象如下,你但願插件顯示數據項的值。例如,你但願DatePicker 默認顯示數據項的一個date屬性。在這種狀況下,你須要利用rendered()回調建立插件並用數據項的值初始化插件。

例如,下面的代碼顯示聯繫人的名單,rendered() 用來建立一個jQuery UI Datepicker插件,並在模板中的一個input元素中附加插件。DataPicker 的默認值爲聯繫人的生日。

<script type="text/javascript"> 
    $(function() { 
        var contacts = [ 
            { name: "Dave Reed", birthdate: new Date("12/25/1980") }, 
            { name: "Stephen Walther", birthdate: new Date("12/25/1977") }, 
            { name: "Boris Moore", birthdate: new Date("12/25/1934") }, 
            { name: "Eilon Lipton", birthdate: new Date("12/25/2004") }, 
            { name: "Assad Safiullah", birthdate: new Date("12/25/1954") } 
        ]; 
        $("div").append("#template", contacts, { rendered: rendered }); 
    }); 
    function rendered(context, dom) { 
        $("input", dom) 
            .datepicker({ defaultDate: context.dataItem.birthdate }) 
    }     
</script> 
<script id="template" type="text/html"> 
 <div> 
     {%= name %} 
     <br /> 
     birthdate: <input /> 
 </div> 
</script> 
 
<div></div>
 

無表達式模板
若是你不想任何諸如{%=....%}的表達式出如今模板中,你能夠在模板實例中使用rendered函數動態的爲一個元素賦值。例如,下面模板顯示產品清單。注意,模板只包含HTML標記,沒有表達式。


討論(Discussion)
這些都是在論壇討論中提出的問題。

HTML編碼
在目前的提案中,數據項默認是不被編碼的。這意味着,除非你採起額外的行爲,用模板顯示用戶提交的數據的文檔將爲跨站點腳本(XSS)攻擊大開門戶。在早期的提案中,咱們討論爲HTML編碼內容建立一個諸如{!productName }特別分隔符。在目前的提案中,咱們建議使用text()模板函數,而不是用{%= text(productName) %} 。

腳本與樣式模板容器
在目前的提案中,咱們建議在<script id="template" type="text/html"></script>元素中包裹模板。有人提議,較好的選擇是用<style id="template" type="text/html"></style>元素,由於樣式更好的體現了模板表象的性質。

樣式元素的缺點在於不容許出如今文檔的body中,若是你不能修改head元素的內容--例如,你正在使用內容管理系統(CMS)工做,你就沒法建立模板。

從技術上講,當前的提案與用SCRIPT或STYLE包裹模板是兼容的。若是你願意,你可使用Style元素並替換type屬性。

模板應是真正的DOM元素
只有幾我的建議模板應表明真正的DOM元素,這也與ASP . NET Ajax 庫建立模板的方法類似。換句話說,給模板使用標準的DOM元素,用display:none隱藏模板。

使用真正的DOM元素模板的主要缺點在於使用真正的DOM元素會致使不良反作用。例如,考慮下面的代碼:

<div id="template" style="display:none"> 
  <img src="{%= imageUrl %}" /> 
  <br /> {% imageTitle %} 
</div>

在這種狀況下,瀏覽器會嘗試加載位於{%= imageUrl } 地址的圖片,這並非你向發生的。像這樣的例子有不少,一個表達式會致使意想不到的反作用或無效的 HTML。例如,若是是在form中,模板中的input可能post一個實際的值。另外一個很好的例子是在<div id="{ = foo %}"/>其中的id屬性包含無效的值。

修訂歷史2010年2月27日--公佈初步的提案; 2010年3月2日--針對社區反饋更新提案; 將renderTemplate() 重命名爲 template() ; 將分隔符{{ ... }} 改成[[ ... ]] ; 增長[[! ... ]] 用來顯示無編碼的HTML; 移除上下文變量和諸如$id()、$index、writeHtml()和write() 的方法; 增長rendering()函數; 增長templateSetup()函數; 2010年3月9日--針對John Resig 的原型和社區的反饋更新提案; 將template() 重命名爲render() ; 新增DOM操做(如append()); 將表達式中的分隔符改成{%= ... %} ,代碼中的分隔符改成{% ... %} ; 刪除templateSetup()方法。 

相關文章
相關標籤/搜索