KnockoutJS 3.X API 第四章之数据控制流foreach绑定


Posted in Javascript onOctober 10, 2016

foreach绑定

foreach绑定主要用于循环展示监控数组属性中的每一个元素,一般用于table标签中

假设你有一个监控属性数组,每当您添加,删除或重新排序数组项时,绑定将有效地更新UI的DOM-插入或去除相关项目或重新排序现有的DOM元素,不影响任何其他的DOM元素。

当然,也可以配合其他控制流一起适用,例如if和with。

示例1:遍历监控属性数组

本例适用foreach绑定,在一个table标签中循环显示监控属性数组的内容

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

示例2:添加或删除项目

KnockoutJS 3.X API 第四章之数据控制流foreach绑定

UI源码:

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

视图模型源码:

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());

备注1:使用$data

如前两个示例中,foreach后面所跟的是要循环的监控属性数组名称,而foreach内部所跟随的是监控属性数组的项目,例如firstName和lastName。

当你想引用监控属性数组本身的时候,就可以使用这个特殊的上下文$data,他所指的就是监控属性数组本身。

例如,你的监控属性数组中的项目没有明确的项目名称:

<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来引用监控数组属性中的项目,例如:

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

其实这是多此一举的。因为firstName的默认前缀就是$data,所以一般可以省略不写。

备注2:使用$index、$parent和其他的上下文标记

你可能会发现,在示例2中使用了$index来代替了监控属性数组的索引值(从0开始),当然$index是一个监控属性,他会根据数据的变化而自动变化,就像示例2中展示的一样。

而$parent所代表的是在foreach绑定循环外的某个绑定属性,例如:

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

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

在备注1中,使用$data.varibale的方式访问的监控属性数组的项目,但在有些时候你可以需要给这些项目起个别名,那就是可以使用as,例如:

<ul data-bind="foreach: { data: people, as: 'person' }"></ul>

现在,只要在foreach循环中,使用person,就可以访问数组中的元素了。

也有些嵌套使用的例子,这中会更加复杂一些,例如:

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

备注4:不使用foreach容器并生产内容

在某些情况下,可能需要复制容器标签的内容,例如生成如下DOM:

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

像这种情况,我们就无法在ul标签中使用foreach绑定,解决这个问题的方法就是使用无容器的foreach绑定:

<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 -->。就想之前章节提到的虚拟绑定一样。

备注5:检测并处理数组变化

当您修改模型数组的内容(通过添加,移动或删除其项),在foreach绑定使用一个有效的差分算法计算方法当出发生了什么变化的时候。

当您添加数组项,foreach会使您的模板的新副本,并将其插入到现有的DOM
当你删除数组项,foreach将直接删除相应的DOM元素
当你重新排序数组项(保持相同的对象实例),foreach通常只要将相应的DOM元素融入自己的新位置

备注6:销毁项目

有时你可能想为数据项目做删除标记,但实际上并不真正删除该项目。这中方式被称为非破坏性的删除。

默认情况下,foreach绑定将跳过(即隐藏)标记为删除任何数组项。如果你想显示这些项目,使用includeDestroyed选项。例如,

<div data-bind='foreach: { data: myArray, includeDestroyed: true }'>
...
</div>

备注7:使用动画过渡,提高用户体验

如果您需要在生成的DOM元素运行一些定制逻辑,你可以使用afterRender/ afterAdd/beforeRemove/ beforeMove/ afterMove这些回调函数。

下面是一个使用afterAdd的一个简单的例子,应用经典的“黄色淡出”的效果,以新增项目。它需要的jQuery插件的颜色,使背景色彩的动画。

KnockoutJS 3.X API 第四章之数据控制流foreach绑定

源码如下:

<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第一次初始化执行的回调函数。KO提供下列参数回调:

插入的DOM元素的数组

数据项

afterAdd-当foreach添加新项目后的回调函数。KO提供下列参数回调:

DOM节点
添加的数组元素的索引
添加的数组元素

beforeRemove-当一个数组项已被删除的回调函数。这里最明显的用jQuery的$(domNode).fadeOut()动画去除相应的DOM节点。KO提供下列参数回调:

删除一个DOM节点

被删除的数组元素的索引

删除的数组元素

beforeMove-当一个数组项在数组中已经改变了位置的回调函数,但之前相应的DOM节点已被移动。需要注意的是beforeMove适用于所有的数组元素的指标发生了变化,因此,如果你在一个数组的开头插入一个新的项目,然后回调(如果指定)将触发所有其他元素,因为它们的索引位置增加了一个。您可以使用beforeMove存储在受影响元素的原始屏幕坐标,这样你可以在afterMove回调动画动作。KO提供下列参数回调:

可能是移动的DOM节点

移动的数组元素的索引

移动的数组元素

afterMove-数组项在数组中已经改变位置的回调函数,KO提供下列参数回调:

可能已经移动的DOM节点

移动的数组元素的索引

移动的数组元素

以上所述是小编给大家介绍的KnockoutJS 3.X API 第四章之数据控制流foreach绑定,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery Ajax方法调用 Asp.Net WebService 的详细实例代码
Apr 27 Javascript
JavaScript子窗口ModalDialog中操作父窗口对像
Dec 11 Javascript
10分钟学会写Jquery插件实例教程
Sep 06 Javascript
js实现数字每三位加逗号的方法
Feb 05 Javascript
Javascript设计模式之观察者模式(推荐)
Mar 29 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
Jan 04 Javascript
Jil,高效的json序列化和反序列化库
Feb 15 Javascript
js判断文件类型大小并给出提示的实现方法
Jan 03 Javascript
ionic4+angular7+cordova上传图片功能的实例代码
Jun 19 Javascript
vue实现手机号码的校验实例代码(防抖函数的应用场景)
Sep 05 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
Dec 10 Javascript
使用React代码动态生成栅格布局的方法
May 24 Javascript
KnockoutJS 3.X API 第四章之数据控制流if绑定和ifnot绑定
Oct 10 #Javascript
KnockoutJS 3.X API 第四章之数据控制流with绑定
Oct 10 #Javascript
JS命令模式例子之菜单程序
Oct 10 #Javascript
KnockoutJS 3.X API 第四章之数据控制流component绑定
Oct 10 #Javascript
KnockoutJS 3.X API 第四章之click绑定
Oct 10 #Javascript
KnockoutJS 3.X API 第四章之事件event绑定
Oct 10 #Javascript
KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定
Oct 10 #Javascript
You might like
PHP FOR MYSQL 代码生成助手(根据Mysql里的字段自动生成类文件的)
2011/07/23 PHP
php数组操作之键名比较与差集、交集赋值的方法
2014/11/10 PHP
PHP实现的比较完善的购物车类
2014/12/02 PHP
PHP实现股票趋势图和柱形图
2015/02/07 PHP
php使用curl出现Expect:100-continue解决方法
2015/03/03 PHP
示例详解Laravel的注册重构
2016/08/14 PHP
大家未必知道的Js技巧收藏
2008/04/07 Javascript
JavaScript 动态添加表格行 使用模板、标记
2009/10/24 Javascript
ExtJS 下拉多选框lovcombo
2010/05/19 Javascript
深入理解Angularjs 脏值检测
2018/10/12 Javascript
nuxt.js中间件实现拦截权限判断的方法
2018/11/21 Javascript
vue eslint简要配置教程详解
2019/07/26 Javascript
nuxt框架中对vuex进行模块化设置的实现方法
2019/09/06 Javascript
Vue中正确使用Element-UI组件的方法实例
2020/10/13 Javascript
10个易被忽视但应掌握的Python基本用法
2015/04/01 Python
用ReactJS和Python的Flask框架编写留言板的代码示例
2015/12/19 Python
Python3连接MySQL(pymysql)模拟转账实现代码
2016/05/24 Python
Python中的字符串操作和编码Unicode详解
2017/01/18 Python
python科学计算之scipy——optimize用法
2019/11/25 Python
html5关于外链嵌入页面通信问题(postMessage解决跨域通信)
2020/07/20 HTML / CSS
Internet主要有哪些网络群组成
2015/12/24 面试题
积极分子思想汇报
2014/01/04 职场文书
护士检查书
2014/01/17 职场文书
《圆明园的毁灭》教学反思
2014/02/28 职场文书
家长通知书家长评语
2014/04/17 职场文书
活动倡议书范文
2014/05/13 职场文书
员工安全生产承诺书
2014/05/22 职场文书
市场营销专业求职信
2014/06/17 职场文书
运动会广播稿100字
2014/09/14 职场文书
幼儿教师自我剖析材料
2014/09/29 职场文书
2014年小学图书室工作总结
2014/12/09 职场文书
陕西导游词
2015/02/04 职场文书
诉讼和解协议书
2016/03/23 职场文书
MySQL 重写查询语句的三种策略
2021/05/10 MySQL
解决Navicat for Mysql连接报错1251的问题(连接失败)
2021/05/27 MySQL
table设置超出部分隐藏,鼠标移上去显示全部内容的方法
2022/12/24 HTML / CSS