目的

template绑定(模板绑定)使用渲染模板的结果填充关联的DOM元素。 模板是一种简单方便的方式来构建复杂的UI结构 。

下面介绍两种使用模板绑定的方法:

  • 本地模板是支持foreach,if,with和其他控制流绑定的机制。 在内部,这些控制流绑定捕获元素中包含的HTML标记,并将其用作模板以针对任意数据项进行呈现。 此功能内置在Knockout中,不需要任何外部库。
  • 基于字符串的模板是一种将Knockout连接到第三方模板引擎的方法。 Knockout会将您的模型值传递给外部模板引擎,并将生成的标记字符串注入到文档中。 请参阅下面的备注6使用jquery.tmpl和Underscore模板引擎的示例。

    参数

  • 快速语法:如果你只是提供一个字符串值,KO会将其解释为要渲染的模板的ID。它提供给模板的数据将是您当前的模型对象。

  • 要获得更多控件,请传递具有以下属性的某些组合的JavaScript对象:

  • name — 包含要渲染的模板的元素的ID - 有关如何以编程方式更改此设置,请参见备注5。
  • nodes —直接传递DOM节点数组以用作模板。这应该是一个不可观察的数组,并注意元素将从他们当前的父(如果他们有一个)中删除。如果您还为name传递了一个非空值,则忽略此选项。
  • data — 要提供为要呈现的模板的数据的对象。如果省略此参数,KO将查找foreach参数,或者使用当前模型对象返回。
  • if — 如果提供此参数,那么只有在指定的表达式求值为true(或true-ish值)时,才会呈现模板。这可以有助于防止null observable在填充之前与模板绑定。
  • foreach — 指示KO以“foreach”模式渲染模板 - 有关详细信息,请参见备注2。
  • as — 当与foreach结合使用时,为正在呈现的每个项目定义别名 - 有关详细信息,请参见备注3。
  • afterRender, afterAddbeforeRemove — 要针对呈现的DOM元素调用的回调函数 - 请参阅备注4

    备注1:渲染命名模板

    通常,当您使用控制流绑定(foreach,with,if等)时,不需要给您的模板命名:它们是由DOM元素内的标记隐式和匿名定义的。 但是如果你想要,你可以将模板分解成一个单独的元素,然后通过名称引用它们:

    Participants

    Here are the participants:

    源码:

    <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'标记使用两次:一次用于买方,一次用于卖方。 请注意,模板标记被包装在<script type =“text / html”>中 - 必须使用虚拟类型属性,以确保标记不会作为JavaScript执行,Knockout不会尝试对该标记应用绑定,除非 它被用作模板。

    使用命名模板不是经常被用到,但有时它可以帮助减少重复的标记。

    备注2:对命名模板使用“foreach”选项

    Participants

    Here are the participants:

    源码:

    <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>
    <script>
    function MyViewModel() {
    this.people = [
    { name: 'Franklin', credits: 250 },
    { name: 'Mario', credits: 5800 }
    ]
    }
    ko.applyBindings(new MyViewModel());
    </script>

    这给出了与在您使用foreach的元素内直接嵌入匿名模板相同的结果,例如:

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

    备注3:使用“as”给“foreach”项目一个别名

    当嵌套foreach模板时,引用层次结构中较高级别的项目通常很有用。 一种方法是在绑定中引用$ parent或其他绑定上下文变量。

    然而,一个更简单和更优雅的选项是使用as来为你的迭代变量声明一个名字。 例如:

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

    注意与as相关联的字符串值“employee”。 现在在这个foreach循环中的任何地方,你的子模板中的绑定将能够引用employee来访问正在呈现的employee对象。

    如果你有多个嵌套的foreach块,这是非常有用的,因为它给你一个明确的方法来引用层次结构中更高级别上声明的任何命名项。 这是一个完整的例子,显示季节可以在渲染一个月时被引用:

    源码:

    <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>

    提示:请记住将字符串字面值传递为as(例如,as:'season',而不是as:season),因为您要出给一个新变量命名,而不是读取已经存在的变量的值。

    备注4:使用afterRender, afterAdd,  beforeRemove

    有时,您可能希望对由模板生成的DOM元素运行自定义后处理逻辑。 例如,如果您使用JavaScript窗口部件库(如jQuery UI),则可能需要拦截模板的输出,以便可以对其运行jQuery UI命令,将一些渲染的元素转换为日期选择器,滑块或别的什么东西。

    通常,对DOM元素执行此类后处理的最佳方法是编写自定义绑定,但如果您只想访问模板发出的原始DOM元素,则可以使用afterRender。

    传递函数引用(函数文字,或给出视图模型上的函数名称),Knockout将在渲染或重新渲染模板后立即调用它。 如果你使用foreach,Knockout将为添加到你的observable数组的每个项目调用你的afterRender回调函数。 例如,

    <div data-bind='template: { name: "personTemplate",
    data: myData,
    afterRender: myPostProcessingLogic }'> </div>

    并在视图模型(即包含myData的对象)上定义相应的函数:

    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,并且只希望通知有关特定要添加或正在删除的元素,则可以使用afterAdd和beforeRemove。 有关详细信息,请参阅第四章foreach绑定的文档

    备注5:动态选择使用哪个模板

    如果有多个命名模板,则可以为名称选项传递observable。 随着observable的值被更新,元素的内容将使用适当的模板重新渲染。 或者,您可以传递回调函数来确定要使用哪个模板。 如果您使用的是foreach模板模式,Knockout将评估数组中每个项目的函数,并将该项目的值作为唯一的参数。 否则,函数将给出数据选项的值,或者返回提供整个当前模型对象。

    源码:

    <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值,那么当这些值发生变化时,绑定就会更新。 这将导致使用适当的模板重新呈现数据。

    如果你的函数包含第二个参数,那么它将接收整个绑定上下文。 然后,当动态选择模板时,可以访问$ parent或任何其他绑定上下文变量。 例如,您可以修改上述代码段,如下所示:

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

    备注6:使用jQuery.tmpl,一个外部的基于字符串的模板引擎

    在绝大多数情况下,Knockout的本地模板和foreach,if,with和其他控制流绑定将需要构建一个任意复杂的UI。 但是,如果您希望与外部模板库(例如Underscore模板引擎或jquery.tmpl)集成,Knockout提供了一种方法。

    默认情况下,Knockout支持jquery.tmpl。 要使用它,您需要按以下顺序引用以下库:

    <!-- First jQuery -->     <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <!-- Then jQuery.tmpl --> <script src="jquery.tmpl.js"></script>
    <!-- Then Knockout --> <script src="knockout-x.y.z.js"></script>

    然后,您可以在模板中使用jQuery.tmpl语法。 例如

    <h1>People</h1>
    <div data-bind="template: 'peopleList'"></div> <script type="text/html" id="peopleList">
    {{each people}}
    <p>
    <b>${name}</b> is ${age} years old
    </p>
    {{/each}}
    </script> <script type="text/javascript">
    var viewModel = {
    people: ko.observableArray([
    { name: 'Rod', age: 123 },
    { name: 'Jane', age: 125 },
    ])
    }
    ko.applyBindings(viewModel);
    </script>

    这是因为{{each ...}}和$ {...}是jQuery.tmpl语法。 更重要的是,嵌套模板很简单:因为您可以在模板中使用数据绑定属性,您可以简单地在模板中放置一个data-bind =“template:...”来渲染嵌套的模板。

    请注意,截至2011年12月,jQuery.tmpl已不再处于积极开发阶段。 我们建议使用Knockout的本地基于DOM的模板(即foreach,if,with等绑定),而不是jQuery.tmpl或任何其他基于字符串的模板引擎。

  • KnockoutJS 3.X API 第四章(13) template绑定的更多相关文章

    1. KnockoutJS 3.X API 第四章 表单绑定(11) options绑定

      目的 options绑定主要用于下拉列表中(即<select>元素)或多选列表(例如,<select size='6'>).此绑定不能与除<select>元素之外的 ...

    2. KnockoutJS 3.X API 第四章 表单绑定(6) click绑定

      目的 click绑定主要作用是用于DOM元素被点击时调用相关JS函数.最常见用于button.input.a元素. 例如: You've clicked timesClick me var viewM ...

    3. KnockoutJS 3.X API 第四章 表单绑定(7) event绑定

      目的 event绑定即为事件绑定,即当触发相关DOM事件的时候回调函数.例如keypress,mouseover或者mouseout等 例如: Mouse over me Details var vi ...

    4. KnockoutJS 3.X API 第四章 表单绑定(8) submit、enable、disable绑定

      submit绑定目的 submit绑定即为提交绑定,通常用于form元素.这种绑定方式会打断默认的提交至服务器的操作.转而提交到你设定好的提交绑定回调函数中.如果要打破这个默认规则,只需要在回调函数中 ...

    5. KnockoutJS 3.X API 第四章 表单绑定(9) value绑定

      目的 value绑定主要用于DOM元素给视图模型赋值用的.通常用于<input><select><textarea>等元素. value绑定与text绑定的区别在于 ...

    6. KnockoutJS 3.X API 第四章 表单绑定(10) textInput、hasFocus、checked绑定

      textInput绑定目的 textInput绑定主要用于<input>或者<textarea>元素.他提供了DOM和viewmodel的双向更新.不同于value绑定,tex ...

    7. KnockoutJS 3.X API 第四章 表单绑定(12) selectedOptions、uniqueName绑定

      selectedOptions绑定目的 selectedOptions绑定控制当前选择多选列表中的哪些元素. 这旨在与<select>元素和选项绑定结合使用. 当用户选择或取消选择多选列表 ...

    8. KnockoutJS 3.X API 第四章 数据绑定(5) 控制流component绑定

      本节目录: 一个例子 API 备注1:仅模板式的component 备注2:component虚拟绑定 备注3:传递标记到component绑定 内存管理 一个例子 First instance, w ...

    9. KnockoutJS 3.X API 第四章 数据绑定(1) 文本及样式绑定

      目录 本节将介绍六种文本绑定方式: visible绑定 text绑定 html绑定 css绑定 style绑定 attr绑定 可见文本绑定(visible) 使用visible绑定,来控制DOM元素的 ...

    随机推荐

    1. Azure Service Bus 中的身份验证方式 Shared Access Signature

      var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

    2. 注意ArrayAdapter的Add()方法

      ArrayAdapter类可以作为ListView等的适配器资源,并且可以动态向适配器中添加新的数据,这就是ArrayAdapter.Add()方法的作用.但是在使用该方法时如果出错,那就需要检查Ar ...

    3. Python中的random模块,来自于Capricorn的实验室

      Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...

    4. IOS Alcatraz Xcode6.4安装指南

      1.Alcatraz Alcatraz是Xcode上的插件管理器,用过notepad++应该印象深刻,近来在一部新机器 按以前的安装方法安装老是安装不成功.特意查找了下资料,最后安装成功. 2.安装过 ...

    5. javascript 中的事件机制

      1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...

    6. listview选中没有效果

      listview选中没有效果了,设置了android:listselector也没有效果,最后发现是listview中的item布局设置了背景颜色导致,把item的背景色去掉就OK了 http://b ...

    7. 【转载】CentOS6.5_X64下安装配置MongoDB数据库

      [转载]CentOS6.5_X64下安装配置MongoDB数据库 2014-05-16 10:07:09|  分类: 默认分类|举报|字号 订阅      下载LOFTER客户端 本文转载自zhm&l ...

    8. Linux内核--网络栈实现分析(九)--传输层之UDP协议(下)

      本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7549340 更多请查看专栏,地 ...

    9. 搜索栏css代码

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

    10. iptables 四表五链

      netfilter/iptables IP 信息包过滤系统是一种功能强大的工具,可用于添加.编辑和除去规则,这些规则是在做信息包过滤决定时,防火墙所遵循和组成的规则.这些规则存储在专用的信息包过滤表中 ...