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 相关文章推荐
JavaScript 继承详解(四)
Jul 13 Javascript
jQuery解决iframe高度自适应代码
Dec 20 Javascript
纯js分页代码(简洁实用)
Nov 05 Javascript
js的image onload事件使用遇到的问题
Jul 15 Javascript
学习使用bootstrap3栅格系统
Apr 12 Javascript
jQuery AJAX timeout 超时问题详解
Jun 21 Javascript
AngularJS表格详解及示例代码
Aug 17 Javascript
React从react-router路由上做登陆验证控制的方法
May 10 Javascript
在vue项目中使用Jquery-contextmenu插件的步骤讲解
Jan 27 jQuery
React+TypeScript+webpack4多入口配置详解
Aug 08 Javascript
JS实现滑动拼图验证功能完整示例
Mar 29 Javascript
详解vue父子组件状态同步的最佳方式
Sep 10 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你的验证码安全码?
2007/01/02 PHP
laravel5.4利用163邮箱发送邮件的步骤详解
2017/09/22 PHP
Yii框架实现对数据库的CURD操作示例
2019/09/03 PHP
yii2.0框架使用 beforeAction 防非法登陆的方法分析
2019/09/11 PHP
jquery异步循环获取功能实现代码
2010/09/19 Javascript
JavaScript-RegExp对象只能使用一次问题解决方法
2014/06/23 Javascript
JavaScript组合拼接字符串的效率对比测试
2014/11/06 Javascript
node.js中的fs.readlink方法使用说明
2014/12/17 Javascript
JavaScript声明变量名的语法规则
2015/07/10 Javascript
JavaScript实现图片轮播的方法
2015/07/31 Javascript
利用CSS3在Angular中实现动画
2016/01/15 Javascript
javascript如何实现360度全景照片问题汇总
2016/04/04 Javascript
深入理解(function(){... })();
2016/08/16 Javascript
React组件的三种写法总结
2017/01/12 Javascript
vue进行图片的预加载watch用法实例讲解
2018/02/07 Javascript
微信小程序实现通过双向滑动缩放图片大小的方法
2018/12/30 Javascript
VUE中使用HTTP库Axios方法详解
2020/02/05 Javascript
JS实现TITLE悬停长久显示效果完整示例
2020/02/11 Javascript
Python实现接受任意个数参数的函数方法
2018/04/21 Python
pygame游戏之旅 创建游戏窗口界面
2018/11/20 Python
OpenCV-Python 摄像头实时检测人脸代码实例
2019/04/30 Python
django rest framework vue 实现用户登录详解
2019/07/29 Python
django框架模型层功能、组成与用法分析
2019/07/30 Python
django-xadmin根据当前登录用户动态设置表单字段默认值方式
2020/03/13 Python
python破解同事的压缩包密码
2020/10/14 Python
python 利用toapi库自动生成api
2020/10/19 Python
详解selenium + chromedriver 被反爬的解决方法
2020/10/28 Python
关于多种方式完美解决Python pip命令下载第三方库的问题
2020/12/21 Python
PUMA官方商城:世界领先的运动品牌之一
2016/11/16 全球购物
Answear匈牙利:来自全球200多个知名时尚品牌
2017/04/21 全球购物
SportsDirect.com马来西亚:英国第一体育零售商
2018/11/21 全球购物
大学生个人自荐信样本
2014/03/02 职场文书
财务部岗位职责
2015/02/03 职场文书
详解java如何集成swagger组件
2021/06/21 Java/Android
python树莓派通过队列实现进程交互的程序分析
2021/07/04 Python
Python学习开发之图形用户界面详解
2021/08/23 Python