KnockOut文檔--模板綁定


目的

模板綁定使用數據render模板,然后把渲染的結果填充到Dom樹中。模板通過重復或嵌套塊(通常視圖模型數據的函數用一種簡單,方便的方式來建立復雜的UI結構

有兩種方式使用模板:

 

  • Native templating它由foreach, if, with,或其它控制流綁定(control flow bindings)組成 。 這些控制流綁定捕捉包含你指定的所有HTML標記,把它作為模板來呈現任意數據項目,此特性由Knockout內置,無需任何擴展庫。
  • String-based templating   Knockout使用第三方模板引擎來支持字符串模板. Knockout 通過傳入字符串參數,調用擴展模板庫,將返回字符串注入文檔中. 以下例子使用 jquery.tmpl 和 Underscore 模板引擎.

參數

  • 主要參數

    • 簡化語法: 如果你使用一個字符串值, KO 將把它使用一個模板ID來呈現. 它提供的數據模板是你的當前模型對象.

    • 復雜控制, 通過以下方式的Javascript 對象來綁定:

      • name —包含你想呈現的模板ID  - 參見 Note 5 .
      • data — 你想呈現的data對象. 如省略此參數, KO 將查找 foreach 參數, or will fall back on using your current model object.
      • if — 如有此參數, 則在if表達式為true時渲染模板.例如:先判斷觀察對象為空,再決定是否綁定模板
      • foreach — 通過“foreach” 循環進行綁定- 參見 Note 2  .
      • as — 使用 foreach時,用於定義別名 - 參見Note 3 .
      • afterRender, afterAdd, or beforeRemove — 渲染元素的回調函數 -參見 Note 4

Note 1: 渲染命名 template

一般說來,如果使用控制流綁定 (foreach, with, if, etc.)時,無需給模板命名: 你的Dom元素中已經隱式的給它命名了. 但你也可以顯式的給模板命名,並引用它

<h2>Participants</h2>
Here are the participants:
<div data-bind="template: { name: 'person-template', data: buyer }"></div>
<div data-bind="template: { name: 'person-template', data: seller }"></div>
 
<script type="text/html" id="person-template">
    <h3 data-bind="text: name"></h3>
    <p>Credits: <span data-bind="text: credits"></span></p>
</script>
 
<script type="text/javascript">
     function MyViewModel() {
         this.buyer = { name: 'Franklin', credits: 250 };
         this.seller = { name: 'Mario', credits: 5800 };
     }
     ko.applyBindings(new MyViewModel());
</script>

 

上例中,person-template 被使用了兩次:buyer 一次, seller一次. 注意:模板被包裹在 <script type="text/html">標記中,type 屬性是必須的,用於區別正常的javascript代碼, 不會被Knockout 當作標記來綁定.

命名模板並不常用,但有的時候能派上用場.

 

Note 2: 在命名模板中使用“foreach”項

以下方式在命名模板中使用foreach:

<h2>Participants</h2>
Here are the participants:
<div data-bind="template: { name: 'person-template', foreach: people }"></div>
 
<script type="text/html" id="person-template">
    <h3 data-bind="text: name"></h3>
    <p>Credits: <span data-bind="text: credits"></span></p>
</script>
 
 function MyViewModel() {
     this.people = [
         { name: 'Franklin', credits: 250 },
         { name: 'Mario', credits: 5800 }
     ]
 }
 ko.applyBindings(new MyViewModel());

其實,下面的代碼使用foreach是最直接的,無需命名模板:

<div data-bind="foreach: people">
    <h3 data-bind="text: name"></h3>
    <p>Credits: <span data-bind="text: credits"></span></p>
</div>

 

Note 3: 通過as給 “foreach”項一個別名

使用as 將有助於更好的使用foreach. 例如:

<ul data-bind="template: { name: 'employeeTemplate',
                                  foreach: employees,
                                  as: 'employee' }"></ul>

注意: 'employee' 通過 as與foreach中的項相關聯了.現在你可以在foreach 循環中通過 employee來訪問foreach項,達到更好控制渲染的目的

此功能主要用於foreach嵌套, 以下示例展示了上層循環season如何控制下層循環month的:

<ul data-bind="template: { name: 'seasonTemplate', foreach: seasons, as: 'season' }"></ul>
 
<script type="text/html" id="seasonTemplate">
    <li>
        <strong data-bind="text: name"></strong>
        <ul data-bind="template: { name: 'monthTemplate', foreach: months, as: 'month' }"></ul>
    </li>
</script>
 
<script type="text/html" id="monthTemplate">
    <li>
        <span data-bind="text: month"></span>
        is in
        <span data-bind="text: season.name"></span>
    </li>
</script>
 
<script>
    var viewModel = {
        seasons: ko.observableArray([
            { name: 'Spring', months: [ 'March', 'April', 'May' ] },
            { name: 'Summer', months: [ 'June', 'July', 'August' ] },
            { name: 'Autumn', months: [ 'September', 'October', 'November' ] },
            { name: 'Winter', months: [ 'December', 'January', 'February' ] }
        ])
    };
    ko.applyBindings(viewModel);
</script>

注意: 別忘記給值加上引號 (e.g., as: 'season', 別寫為 as: season),

 

Note 4: 使用“afterRender”, “afterAdd”, and “beforeRemove”

有時需要定制生成模板的邏輯。例如,當你使用 jQuery UI組件時, 可能需要將模板轉化為對應的各種控件.

一般說來, 使用 custom binding,來處理以上需求較好,但有可能你也需要訪問原始的模板生成dom元素,此時,你可以使用afterRender.

渲染模板之后.KO將調用afterRender .如果使用了 foreach, Knockout 將在每個項加到observable數組后回調 afterRender.例如:

<div data-bind='template: { name: "personTemplate",
                            data: myData,
                            afterRender: myPostProcessingLogic }'> </div>
.....
viewModel.myPostProcessingLogic = function(elements) {
    // "elements" is an array of DOM nodes just rendered by the template
    // You can add custom post-processing logic here
}

如果在foreach只想處理增加和刪除, 可使用afterAddbeforeRemove 來代替,參見文檔 foreach binding.

Note 5: 動態選擇模板

如果有多個模板, 可使用回調函數來決定使用哪一個,當然函數們得有自己的name。如果使用的是foreach模板, KO在每次foreach項的時候都會執行函數,其參數為整個item對象。.Otherwise, the function will be given the data option’s value or fall back to providing your whole current model object.

例如:

<ul data-bind='template: { name: displayMode,
                           foreach: employees }'> </ul>
 
<script>
    var viewModel = {
        employees: ko.observableArray([
            { name: "Kari", active: ko.observable(true) },
            { name: "Brynn", active: ko.observable(false) },
            { name: "Nora", active: ko.observable(false) }
        ]),
        displayMode: function(employee) {
            // Initially "Kari" uses the "active" template, while the others use "inactive"
            return employee.active() ? "active" : "inactive";
        }
    };
 
    // ... then later ...
    viewModel.employees()[1].active(true); // Now "Brynn" is also rendered using the "active" template.
</script>

如果在函數中使用 observable 值, 那么它的值更新后對應的綁定也會更新. 這樣數據就可以選擇合適的模板來呈現。

如果在函數中使用了第二個參數,那它將作為 binding context對象來處理.當動態選擇模板時,你可以訪問$parent 或其它的 binding context 變量 。例如:

displayMode: function(employee, bindingContext) {
    // Now return a template name string based on properties of employee or bindingContext
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM