KnockoutJS 3.X API 第四章(13) template绑定
目的
template绑定(模板绑定)使用渲染模板的结果填充关联的DOM元素。 模板是一种简单方便的方式来构建复杂的UI结构 。
下面介绍两种使用模板绑定的方法:
参数
快速语法:如果你只是提供一个字符串值,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, afterAdd, beforeRemove — 要针对呈现的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绑定的更多相关文章
- KnockoutJS 3.X API 第四章 表单绑定(11) options绑定
目的 options绑定主要用于下拉列表中(即<select>元素)或多选列表(例如,<select size='6'>).此绑定不能与除<select>元素之外的 ...
- KnockoutJS 3.X API 第四章 表单绑定(6) click绑定
目的 click绑定主要作用是用于DOM元素被点击时调用相关JS函数.最常见用于button.input.a元素. 例如: You've clicked timesClick me var viewM ...
- KnockoutJS 3.X API 第四章 表单绑定(7) event绑定
目的 event绑定即为事件绑定,即当触发相关DOM事件的时候回调函数.例如keypress,mouseover或者mouseout等 例如: Mouse over me Details var vi ...
- KnockoutJS 3.X API 第四章 表单绑定(8) submit、enable、disable绑定
submit绑定目的 submit绑定即为提交绑定,通常用于form元素.这种绑定方式会打断默认的提交至服务器的操作.转而提交到你设定好的提交绑定回调函数中.如果要打破这个默认规则,只需要在回调函数中 ...
- KnockoutJS 3.X API 第四章 表单绑定(9) value绑定
目的 value绑定主要用于DOM元素给视图模型赋值用的.通常用于<input><select><textarea>等元素. value绑定与text绑定的区别在于 ...
- KnockoutJS 3.X API 第四章 表单绑定(10) textInput、hasFocus、checked绑定
textInput绑定目的 textInput绑定主要用于<input>或者<textarea>元素.他提供了DOM和viewmodel的双向更新.不同于value绑定,tex ...
- KnockoutJS 3.X API 第四章 表单绑定(12) selectedOptions、uniqueName绑定
selectedOptions绑定目的 selectedOptions绑定控制当前选择多选列表中的哪些元素. 这旨在与<select>元素和选项绑定结合使用. 当用户选择或取消选择多选列表 ...
- KnockoutJS 3.X API 第四章 数据绑定(5) 控制流component绑定
本节目录: 一个例子 API 备注1:仅模板式的component 备注2:component虚拟绑定 备注3:传递标记到component绑定 内存管理 一个例子 First instance, w ...
- KnockoutJS 3.X API 第四章 数据绑定(1) 文本及样式绑定
目录 本节将介绍六种文本绑定方式: visible绑定 text绑定 html绑定 css绑定 style绑定 attr绑定 可见文本绑定(visible) 使用visible绑定,来控制DOM元素的 ...
随机推荐
- Github 新的项目管理模式——Projects
Github 新的项目管理模式--Projects Issues Github 中传统的项目管理是使用 issue 和 pull request 进行的,这部分内容不是本文重点,不再赘述. 但有一些功 ...
- VS2010 网页错误
VS2010向导添加消息处理时,弹出以上错误,原因之一为: 类内没有定义IDD的宏
- getline函数彻底说明
因为之前每次使用这个函数都要在网上查一遍,觉得很麻烦,这次就认真地整理一下,希望写完之后就记住. getline函数其实有两个: 一个是全局函数,include<cstring>, 原型是 ...
- [UCSD白板题] Fractional Knapsack
Problem Introduction Given a set of items and total capacity of a knapsack,find the maximal value of ...
- [UCSD白板题] Greatest Common Divisor
Problem Introduction The greatest common divisor \(GCD(a, b)\) of two non-negative integers \(a\) an ...
- Inno setup中定制安装路径
我的程序修改了安装界面,所以我的界面中提供了更改安装路径的方法. 用户修改后的路径会被传回inno setup脚本,脚本中需要做的事情如下: 1,写一个函数,来返回新的安装路径,如: function ...
- java.util.zip.ZipException: invalid entry size 解决办法
启动maven项目时报java.util.zip.ZipException: invalid entry size (expected 7612 but got 5955 bytes) 可能是mave ...
- IOS开发——使用数据库
IOS开发——使用FMDB数据库 简介 需求作用: 如果需要保存大量的结构较为复杂的数据的时候,使用数据库,例如交规考试项目 1.数据库的基本介绍 数据库(DB)是一种数据模型组织起来并存放存储管理的 ...
- 解决Ubuntu发热量大的问题
转自:http://blog.csdn.net/tracker_w/article/details/8801971 用Ubuntu 的朋友应该都有体会,开机不久风扇就开始狂转,本本也会很热.据说是双显 ...
- savepoint原理
保存点 在MySQL中, 保存点SAVEPOINT属于事务控制处理部分.利用SAVEPOINT可以回滚指定部分事务,从而使事务处理更加灵活和精细.SAVEPOINT相关的SQL语句如下 SAVEPOI ...