foreach绑定对于数组中的每个元素复制一节标记语言,也就是html,而且将这节标记语言和数组里面的每个元素绑定。当咱们呈现一组list数据,或者一个表格的时候,十分有用。javascript
若是你绑定的数组是一个"监控数组" ,observable array,(和wpf里面的ObservableCollection<T>差很少)。当你添加或移除,或者从新排序数组里面的元素的时候,会动态的更新UI界面。而且此时并不会影响原先的DOM元素。这样比咱们直接从新生成一个数组而且绑定元素高效的多。html
固然,foreach也支持嵌套绑定,或者和其余工做流绑定例如if 或者with。java
对数组中的每个元素生成一行数据的只读表。jquery
@{ Layout = null; } <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <table> <thead> <tr><th>First name</th><th>Last name</th></tr> </thead> <tbody data-bind="foreach: people"> <tr> <td data-bind="text: firstName"></td> <td data-bind="text: lastName"></td> </tr> </tbody> </table> <script type="text/javascript"> ko.applyBindings({ people: [ { firstName: 'Bert', lastName: 'Bertington' }, { firstName: 'Charles', lastName: 'Charlesforth' }, { firstName: 'Denise', lastName: 'Dentiste' } ] }); </script>
效果以下:数组
First name | Last name |
---|---|
Bert | Bertington |
Charles | Charlesforth |
Denise | Dentiste |
下面这个例子展现了,若是你绑定的数组是一个监控数组,那么这个UI界面将会和数组的改变同步。app
dom
@{ Layout = null; } <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <h4>People</h4> <ul data-bind="foreach: people"> <li> Name at position <span data-bind="text: $index"> </span>: <span data-bind="text: name"> </span> <a href="#" data-bind="click: $parent.removePerson">Remove</a> </li> </ul> <button data-bind="click: addPerson">Add</button> <script type="text/javascript"> function AppViewModel() { var self = this; self.people = ko.observableArray([ { name: 'Bert' }, { name: 'Charles' }, { name: 'Denise' } ]); self.addPerson = function () { self.people.push({ name: "New at " + new Date() }); }; self.removePerson = function () { self.people.remove(this); } } ko.applyBindings(new AppViewModel()); </script>
主参数函数
给foreach传过去你但愿迭代的数组。对于每个数组元素foreach绑定会输出一段超文本标记语言。post
你也能够给foreach绑定传递一个含有data属性的 的你想要去迭代的javascript字面量,这个字面量也能够有其它属性, 例如 afterAdd
或者includeDestroyed
,能够看接下来的例子。优化
若是你绑定的是一个监控数组,对数组内容的增长或者移除foreach绑定将会在UI界面上增长或者移除dom元素。
其它参数
就像在上面的例子中展现的。foreach绑定可以指向数组每一条数据的属性。例如例1中的firstName 和lastName.可是,若是咱们想指向数组自己,应该怎么办,此时咱们能够用$.data.在foreach绑定中,$data指的就是数组的当前的元素项。
@{ Layout = null; } <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <ul data-bind="foreach: months"> <li> The current item is: <b data-bind="text: $data"></b> </li> </ul> <script type="text/javascript"> ko.applyBindings({ months: ['Jan', 'Feb', 'Mar', 'etc'] }); </script>
效果以下
固然,若是你非要这样作的话, 你也能够给你指向的每个属性加上一个 $data前缀
.例如,你也能够在例1中像下面这样写,虽然这样写不必,由于它的默认上下文就是$data
:
<td data-bind=
"text: $data.firstName"
></td>
|
就像咱们在例2 中看到的那样。你可一用$index 来表示数组中当前项从零开始的索引。 $index是一个监控属性,当数组的项变动的时候$index也会自动更新。
一样,你也能够用$parent来指向foreach外的数据。若是foreach对应的是viewmodel的直接子元素,那么$parent就是指的viewmodel
<h1 data-bind="text: blogPostTitle"></h1> <ul data-bind="foreach: likes"> <li> <b data-bind="text: name"></b> likes the blog post <b data-bind="text: $parent.blogPostTitle"></b> </li> </ul>
更多关于 $index和$parent的资料能够去看 binding context properties.
就想在要点1里面描述的那样。咱们能够引用每个数组项用 $data
上下文变量。但在一些特殊状况下,给当前项一个别名用起来更方便。尤为在多层嵌套结构中:
别名使用的语法以下:
<ul data-bind="foreach: { data: people, as: 'person' }"></ul>
如今在foreach循环的任何地方,绑定均可以根据person指向当前people的数组项。这种语法在多层foreach嵌套的场景中很是有用。例如:
<ul data-bind="foreach: { data: categories, as: 'category' }"> <li> <ul data-bind="foreach: { data: items, as: 'item' }"> <li> <span data-bind="text: category.name"></span>: <span data-bind="text: item"></span> </li> </ul> </li> </ul> <script> var viewModel = { categories: ko.observableArray([ { name: 'Fruit', items: [ 'Apple', 'Orange', 'Banana' ] }, { name: 'Vegetables', items: [ 'Celery', 'Corn', 'Spinach' ] } ]) }; ko.applyBindings(viewModel); </script>
注意: 记得经过as给别名 赋值的时候,传过去一个字符串'category'
, 不是as: category
), 由于咱们是要给变量起一个别名,而不是传递一个标识符变量过去。
在一些状况下,你想要经过foreach绑定一段标记语言html,可是没有供foreach绑定的元素。例以下面这张情景:
<ul> <li class="header">Header item</li> <!-- The following are generated dynamically from an array --> <li>Item A</li> <li>Item B</li> <li>Item C</li> </ul>
这种状况下没有任何元素可供foreach绑定。你不能放到ul里面,由于这时候会把header也放到复制的循环里面去。你也不能放其它的元素在ul里面,由于ul里面只容许放<li>元素。
要想处理这种状况。咱们能够用无容器绑定语法。这中状况是依赖于html的注释标签。以下:
<ul> <li class="header">Header item</li> <!-- ko foreach: myItems --> <li>Item <span data-bind="text: $data"></span></li> <!-- /ko --> </ul> <script type="text/javascript"> ko.applyBindings({ myItems: [ 'A', 'B', 'C' ] }); </script>
<!-- ko -->
和 <!-- /ko -->
注释做为标签的开始和结束,定义了一个虚元素来包含咱们须要重复引用的标记语言在里面,knockout理解这种虚元素语法。咱们能够就当真的有一个html元素来使用它。
当你修改绑定煮熟的值时,例如增长删除移动, foreach绑定用一个有效的区分语法来检测出哪一项被改变了。因此,可以去改变预知匹配的dom元素,这觉得着knockout能够处理任意的和并和同时的改变
foreach
将会根据咱们的模板绘制一个新的dom元素想插入到原先的dom元素中。foreach
将会移除相关的dom元素。foreach
将只会移动相关的dom元素。注意,从新排列时候的排列不是确定的:须要确保咱们的元素想操做足够快。,它被优化只是检测少许的数组项变更。当同时变更的元素不少的时候,knockout会选择执行删除而后从新的添加的方式,而不是只是移动dom元素。
有时你想要将一个数组项标记为删除, 但并非真的删除. 这就是咱们所说的“非毁灭式删除”. 对于更多的资料能够看the destroy function on observableArray
.
默认的foreach 绑定将会只是将被删除的项隐藏。若是你想看并不是真正被删除的项,你能够用 includeDestroyed参数
. 例如
<div data-bind='foreach: { data: myArray, includeDestroyed: true }'>
...
</div>
若是咱们想在生成dom元素的时候添加更多自定义的逻辑咱们能够用,afterRender
/afterAdd
/beforeRemove
/beforeMove
/afterMove
这些回调函数
注意: 这些回调函数时为了生成list改变的时候的动画。对于一些跟复杂的需求,咱们能够用自定义绑定 custom binding 。
@{ Layout = null; } <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/jquery.color-2.1.2.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <ul data-bind="foreach: { data: myItems, afterAdd: yellowFadeIn }"> <li data-bind="text: $data"></li> </ul> <button data-bind="click: addItem">Add</button> <script type="text/javascript"> ko.applyBindings({ myItems: ko.observableArray(['A', 'B', 'C']), yellowFadeIn: function (element, index, data) { $(element).filter("li") .animate({ backgroundColor: 'yellow' }, 200) .animate({ backgroundColor: 'white' }, 800); }, addItem: function () { this.myItems.push('New item'); } }); </script>
效果以下
更多细节:
afterRender
— 当foreach 模板元素被插入document 的时候被调用。第一次初始化和后续每次添加的时候都会调用这个回调函数。会传递下面的参数给回调函数:
afterAdd
—和 afterRender很像
,不过只有增长元素的时候被调用,第一次初始化的时候不会被调用.经常使用来执行元素的淡入$(domNode).fadeIn()
该函数接收下列参数:
beforeRemove
—当一个数组元素被移除,可是相关的dom元素尚未被移除的时候调用,. a beforeRemove
经常使用来执行dom节点的淡出. $(domNode).fadeOut()
这种状况下knockout不知道你要设置多久的淡出时间,因此对于元素的移除,要在该回调函数里面手动移除。该函数接收如下参数:
beforeMove
—当一个数组元素改变了位置,可是相关的dom元素尚未被移动的时候执行. 注意beforeMove 将会对全部索引改变的数组元素有效。
因此,若是你在数组元素的开始位置插入一项,那么aftermove回调函数会对全部的元素有效。由于全部元素的索引都加1改变。咱们能够用. beforeMove
来记录为移动前元素值,而后在aftermove中使用.该回调函数接收如下参数:
afterMove
—在数组元素的位置被改变后调用, 而且是在foreach更新了dom元素后调用 注意afterMove 将会对全部索引改变的数组元素有效。
因此,若是你在数组元素的开始位置插入一项,那么aftermove回调函数会对全部的元素有效。由于全部元素的索引都加1改变。该回调函数接收如下参数:
更多的例子afterAdd
and beforeRemove
请看 animated transitions.
knockout分页demo: http://www.cnblogs.com/santian/p/4342777.html
KnockOut官网:http://knockoutjs.com/documentation/foreach-binding.html
本文地址:http://www.cnblogs.com/santian/p/4379445.html
博客地址:一天两天三天