KnockOut 绑定之foreach绑定(mvc+knockout)

王朝学院·作者佚名  2016-05-22
窄屏简体版  字體: 小  |  中  |  大  |  超大  

KnockOut 绑定之foreach绑定(mvc+knockout)什么时候使用foreach绑定foreach绑定对于数组中的每一个元素复制一节标记语言,也就是html,并且将这节标记语言和数组里面的每一个元素绑定。当我们呈现一组list数据,或者一个表格的时候,十分有用。

如果你绑定的数组是一个"监控数组",observable array,(和wpf里面的ObservableCollection<T>差不多)。当你添加或移除,或者重新排序数组里面的元素的时候,会动态的更新UI界面。并且此时并不会影响原先的DOM元素。这样比我们直接重新生成一个数组并且绑定元素高效的多。

当然,foreach也支持嵌套绑定,或者和其他工作流绑定例如if 或者with。

Example 1: 迭代绑定一个数组对数组中的每一个元素生成一行数据的只读表。

@{ 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 nameLast nameBert

Bertington

Charles

Charlesforth

Denise

Dentiste

Example 2: 给例1中的制度表加上一个增加和移除方法下面这个例子展示了,如果你绑定的数组是一个监控数组,那么这个UI界面将会和数组的改变同步。

PeopleName at position0:BertRemoveName at position1:CharlesRemoveName at position2:DeniseRemoveAdd

@{ 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绑定会输出一段超文本标记语言。

你也可以给foreach绑定传递一个含有data属性的的你想要去迭代的javascript字面量,这个字面量也可以有其它属性,例如afterAdd或者includeDestroyed,可以看接下来的例子。

如果你绑定的是一个监控数组,对数组内容的增加或者移除foreach绑定将会在UI界面上增加或者移除dom元素。

其它参数

无要点1: 用 $data来指向数组的每一条数据就像在上面的例子中展示的。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>

效果如下

The current item is:JanThe current item is:FebThe current item is:MarThe current item is:etc当然,如果你非要这样做的话, 你也可以给你指向的每一个属性加上一个$data前缀.例如,你也可以在例1中像下面这样写,虽然这样写没必要,因为它的默认上下文就是$data:

<td data-bind="text: $data.firstName"></td>

要点 2: 使用$index, $parent, 和其他的上下文属性就像我们在例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.

要点 3: 用as 给foreach项赋值一个别名就想在要点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), 因为我们是要给变量起一个别名,而不是传递一个标识符变量过去。

Note 4: 没有一个容器元素的时候使用foreach在一些情况下,你想要通过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元素来使用它。

要点 5: 数组的改变如何被检测和处理当你修改绑定煮熟的值时,例如增加删除移动, foreach绑定用一个有效的区分语法来检测出哪一项被改变了。所以,能够去改变预知匹配的dom元素,这以为着knockout可以处理任意的和并和同时的改变

当我么增加一个数组项的时候,foreach将会根据我们的模板绘制一个新的dom元素想插入到原先的dom元素中。当我们删除一个项目的时候,foreach将会移除相关的dom元素。当我们移动相关的数组项时),foreach将只会移动相关的dom元素。注意,重新排列时候的

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航