zoukankan      html  css  js  c++  java
  • 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
    }
  • 相关阅读:
    [软件工程基础]第 1 次个人作业
    [软件工程基础]个人项目 数独
    [2017BUAA软件工程]第0次个人作业
    [2017BUAA软工]第零次作业
    NoSQL-流式数据处理与Spark
    C、JAVA存储管理不同点
    数据库之一窥数据库系统
    Java单元测试-覆盖率分析报告自动生成
    Java单元测试-快速上手Junit(进阶)
    Java单元测试-快速上手Junit
  • 原文地址:https://www.cnblogs.com/minttang/p/KnockOut.html
Copyright © 2011-2022 走看看