Knockoutjs 学习系列(二)花式捆绑


Posted in Javascript onJune 07, 2016

在上一篇Knockoutjs 学习系列(一)ko初体验文章中提到,ko中的 data-bind = "XX:OO"绑定大法除了可以绑定text、value等内容,还可以绑定visible、style等外观属性,也可以绑定click、textInput等各种事件,甚至还能控制程序流程。各种花式捆绑,绝对满足你的幻想。

下面简单讲讲各种绑定的使用,主要根据被绑定的属性分成表现类、流程类和交互类三种。

表现类属性

表现类的绑定属性有visible、text、html、css、style、attr几种,除了css表示css的class之外,其他都很好理解。当然了,style里面的命名要与js一致,要去掉-改成驼峰命名,示范如下:

<!--HTML code-->
<div data-bind="visible: shouldShowMessage">You will see this message only when "shouldShowMessage" holds a true value.</div>
<div>Today's message is: <span data-bind="text: myMessage"></span></div>
<div data-bind="html: details"></div>
<div data-bind="css: { profitWarning: currentProfit() < 0 }">CSS class binding test</div>
<div data-bind="style: { color: currentProfit() < 0 ? 'red' : 'black' }">CSS style binding test</div>
<a data-bind="attr: { href: url, title: urltitle }">Report</a> 
// js code
var viewModel = {
shouldShowMessage: ko.observable(true), // Message initially visible
myMessage: ko.observable(), // Initially blank
details: ko.observable(), // Initially blank
currentProfit: ko.observable(150000), // Positive value, so initially we don't apply the "profitWarning" class
currentProfit: ko.observable(150000), // Positive value, so initially black
url: ko.observable("year-end.html"),
urltitle: ko.observable("Report including final year-end statistics")
};
ko.applyBindings(viewModel); // apply binds

效果是这样的:

Knockoutjs 学习系列(二)花式捆绑

表现类的设置比较简单,要注意的一点就是:很多表现类的属性并不需要动态变化,这个时候可以利用viewModel中设置实现数据的集中初始化,但是不要把他们设置成可观察者,如:

// js code
var viewModel = {
shouldShowMessage: ko.observable(true), // Message initially visible
myMessage: '这段文字不需要动态更新' // Initially blank
};

流程类属性

流程类包括foreach、if、ifnot、with和比较高级的"component”绑定,if 和 ifnot 与 visible类似,差别就是:if 会直接从DOM中移除相应的组件,而visible只是控制隐藏显示,组件还是在DOM里面的。with 跟 js 中的 with 也是一样的效果,就是延长了作用域链,简单的来说就是在变量前加了个'前缀.'。这里只介绍一下foreach,component放到和模板绑定一起介绍。

Knockoutjs 学习系列(二)花式捆绑

看看代码:

<!--HTML code-->
<p>测试foreach绑定</p>
<ul data-bind="foreach: people">
<li>
No.<span data-bind="text: $index"> </span>
people's name: <span data-bind="text: name"> </span>
<a href="#" data-bind="click: $parent.removePeople">RemovePeople</a>
<a href="#" data-bind="click: remove">Remove</a>
</li>
</ul>
<input type="button" data-bind="click: addPeople" value="Add" /> 
var listModel = function () {
//设置people数组的值(people实际上是函数数组),使用foreach可以遍历数组对象
//ul,li对应的是 people和people的子项,所以在li内部绑定时,作用域是在people子项{name……}中,为了调用people外部的removePeople需要用到$parent
//如果是调用内部的remove,remove中的this为{name……}对应当前li项,作用域为当前域则不用加 $parent。
this.people = ko.observableArray([
{name: "Mark Zake", remove: function () {
that.people.remove(this); //注意当前对象(就是{name……})和作用域,不用管HTML标签,纯js理解就简单了
}},
{name: "James Lebo", remove: function () {
that.people.remove(this);
}},
{name: "Green Deny", remove: function () {
that.people.remove(this);
}}
]);
//addPeople内部调用了同级people的方法,this会发生改变,应该预先保存this传进去。
var that = this;
this.addPeople = function () {
that.people.push({
name: new Date().toDateString(),
remove: function () {
that.people.remove(this);
}});
};
//remove的对象是整个 li标签,也就是 a标签的父对象。实际上要执行的是 listModel.people.remove(a.parent)
this.removePeople = function() {
that.people.remove(this);
}
};
ko.applyBindings(new listModel());

这里比较容易搞混的是DOM节点与ViewModel的层次对应关系。首先,在ul上应用 foreach 绑定,也就是每个 li 对应每个 people 子项。这一点对应上了之后,就按照 js 的作用域规则去理解即可。说到作用域,不得不提 this,正所谓我待this如初恋,this坑我千百遍。这里小茄在官方版本上加了个remove函数,与官方的removePeople对应起来看就简单了。至于$index, $parent这些变量,按字面意思理解即可。

交互类属性

终于要到重点了,使用ko的最重要原因就是为了处理动态交互的UI展现问题,这里集中介绍一下与表单相关的一些绑定。

(1) click绑定

语法:data-bind="click: clickHandler",这里的clickHandler函数可以是任意函数,并不一定要是ViewModel里的函数,只要能引用到即可。关于click事件有几点需要留意的:

1. 参数传递,ko默认将当前组件作为第一个参数传给clickHandler函数,这里要注意当前的绑定上下文,比如说在with环境中,传回的组件就会变成with组件而不是你想要的当前组件。如果你还需要传递event参数,则将event作为第二个参数传入。如果还需要传入更多的参数,那么就需要使用一个函数包装起来了。如:

<button data-bind="click: function(data, event) { myFunction('param1', 'param2', data, event) }">
Click me
</button>

2. 默认行为的设置(比如链接)

ko默认是禁止默认事件行为的,通常我们为链接绑定点击事件也不会是让其跳转的。不过你如果一定要开启的话,直接在clickHandler里面return true即可。

3. 冒泡

ko默认是允许冒泡的,你可以通过 data-bind="click: clickHandler, clickBubble: false"来设置click事件不冒泡。

(2)event绑定

ko提供了这个接口让用户自定义绑定事件。关于参数传递、默认行为、冒泡等与click绑定是一样的,使用案例:

<div>
<div data-bind="event: { mouseover: enableDetails, mouseout: disableDetails }">
Mouse over me
</div>
<div data-bind="visible: detailsEnabled">
Details
</div>
</div>
<script type="text/javascript">
var viewModel = {
detailsEnabled: ko.observable(false),
enableDetails: function() {
this.detailsEnabled(true);
},
disableDetails: function() {
this.detailsEnabled(false);
}
};
ko.applyBindings(viewModel);
</script>

(3)submit绑定

主要用来做一些验证表单的工作。ko会阻止默认的提交表单动作,并转入submit绑定的函数中。后续需要提交的时候,在绑定事件中 return true即可。

PS: 为什么不在表单中使用 click 事件来处理呢?因为 submit 本来就是被设计用来处理提交事件的,它还能接受回车一类的提交动作,但click则不行。

(4)value 与 textInput 绑定

在输入框绑定 value 和 textInput 看起来效果差不多,但是更推荐使用 textInput 事件进行绑定,因为 textInput 是新增的专门用来处理输入事件的。在上一篇文章中可以看到,使用 value 绑定时(左)输入之后必须要将焦点从输入框中移出才会进行更新,而 textInput (右)是马上进行更新的。

Knockoutjs 学习系列(二)花式捆绑 Knockoutjs 学习系列(二)花式捆绑

虽然,value 绑定也可以通过设置 data-bind="{value: price, valueUpdate: 'afterkeydown'}" 实现与 textInput 一样的效果,但是这个在浏览器中的兼容性并不如 textInput 好。

(5)options绑定(selectedOptions)

在下拉列表中可使用 options 来绑定子项的值,子项既可以是字符串,也可以是 js 对象。上一篇(【Knockoutjs 学习体验之旅】(1)ko初体验)中展示的是字符串,这次就来传个对象:

代码:

<p>Your country:
<select data-bind="options: availableCountries,
optionsText: 'countryName',
value: selectedCountry,
optionsCaption: 'Choose...'"></select>
</p>
<div data-bind="visible: selectedCountry">
<!-- Appears when you select something -->
You have chosen a country with population
<span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>.
</div>
<script type="text/javascript">
// Constructor for an object with two properties
var Country = function(name, population) {
this.countryName = name;
this.countryPopulation = population;
};
var viewModel = {
availableCountries: ko.observableArray([
new Country("UK", 65000000),
new Country("USA", 320000000),
new Country("Sweden", 29000000)
]),
selectedCountry: ko.observable() // Nothing selected by default
};
ko.applyBindings(viewModel);
</script>

这里使用了option来绑定列表框的选项,使用value绑定选中项目。由于选项是 js 对象,所以要用一个 optionText 来指定在列表框中的展示。optionCaption是指无选中任何项目时候的默认显示值。如果我们设定的是多选列表框的话,那么就不能用 value 来绑定选中项目了,这个时候要用到 selectOptions来绑定选中项目。

(6)其他绑定:enable/disable, hasFocus , checked , uniqueName。

这些事件用起来非常简单,就不具体介绍了。最后一个 uniqueName 是用来设置表单控件的唯一 name 属性的,表单中提交到后台时,没有设置 name 属性的值时不会被提交到后台的,所以就有了这么个绑定功能。官网中关于 hasFoucus 还有个比较常用的效果:

Name:

Name: Bert Bertington

Click the name to edit it; click elsewhere to apply changes.

点击上面的姓名就可以变成可编辑状态,失去焦点后又变成普通文字,这种效果用ko实现起来相当简单。

总结

本篇主要简单介绍了knockoutjs中各种绑定的使用方法,使用这些绑定方法的组合就能简单地做好一个需要较多动态交互的UI页面。使用这些方法比较重要的一点就是要记住绑定的都是函数对象,所以可以直接在HTML里面进行操作,这样的话有时候 js 代码结构可以更简单。

官方教程: http://knockoutjs.com/documentation/introduction.html

Javascript 相关文章推荐
可实现多表单提交的javascript函数
Aug 01 Javascript
简单的Jquery全选功能
Nov 07 Javascript
原生js和jquery实现图片轮播淡入淡出效果
Apr 23 Javascript
学习JavaScript设计模式(单例模式)
Nov 26 Javascript
javascript实现粘贴qq截图功能(clipboardData)
May 29 Javascript
VUEJS实战之修复错误并且美化时间(2)
Jun 13 Javascript
JavaScript定时器实现的原理分析
Dec 06 Javascript
ReactNative之键盘Keyboard的弹出与消失示例
Jul 11 Javascript
解决Vue不能检测数组或对象变动的问题
Feb 24 Javascript
AngularJS 应用模块化的使用
Apr 04 Javascript
Vue导出页面为PDF格式的实现思路
Jul 31 Javascript
微信小程序实现上传word、txt、Excel、PPT等文件功能
May 23 Javascript
Knockoutjs 学习系列(一)ko初体验
Jun 07 #Javascript
【经典源码收藏】jQuery实用代码片段(筛选,搜索,样式,清除默认值,多选等)
Jun 07 #Javascript
Javascript之Number对象介绍
Jun 07 #Javascript
Javascript之Math对象详解
Jun 07 #Javascript
分享jQuery网页元素拖拽插件
Dec 01 #Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
Jun 07 #Javascript
全面解析DOM操作和jQuery实现选项移动操作代码分享
Jun 07 #Javascript
You might like
一步一步学习PHP(3) php 函数
2010/02/15 PHP
php中防止伪造跨站请求的小招式
2011/09/02 PHP
根据ip调用新浪api获取城市名并转成拼音
2014/03/07 PHP
PHP strtotime函数用法、实现原理和源码分析
2015/02/04 PHP
Laravel 简单实现Ajax滚动加载示例
2019/10/22 PHP
Ext面向对象开发实践(续)
2008/11/18 Javascript
JavaScript 应用技巧集合[推荐]
2009/08/30 Javascript
JavaScript 学习笔记 Black.Caffeine 09.11.28
2009/11/30 Javascript
JavaScript对象、属性、事件手册集合方便查询
2010/07/04 Javascript
Node.js开发指南中的简单实例(mysql版)
2013/09/17 Javascript
20个实用的JavaScript技巧分享
2014/11/28 Javascript
JavaScript使用concat连接数组的方法
2015/04/06 Javascript
jquery预加载图片的方法
2015/05/27 Javascript
fastclick插件导致日期(input[type=&quot;date&quot;])控件无法被触发该如何解决
2015/11/09 Javascript
js判断复选框是否选中及选中个数的实现代码
2016/05/30 Javascript
Node.js如何自动审核团队的代码
2016/07/20 Javascript
原生js简单实现放大镜特效
2017/05/16 Javascript
vue之nextTick全面解析
2017/05/17 Javascript
JS 中LocalStorage和SessionStorage的使用
2017/08/17 Javascript
在Vue-cli里应用Vuex的state和mutations方法
2018/09/16 Javascript
关于vue的npm run dev和npm run build的区别介绍
2019/01/14 Javascript
用python与文件进行交互的方法
2018/03/01 Python
Pyqt清空某一个QTreeewidgetItem下的所有分支方法
2019/06/17 Python
ansible-playbook实现自动部署KVM及安装python3的详细教程
2020/05/11 Python
通过实例解析python创建进程常用方法
2020/06/19 Python
python如何编写类似nmap的扫描工具
2020/11/06 Python
纯CSS3打造属于自己的“小黄人”
2016/03/14 HTML / CSS
思想品德自我鉴定
2013/10/12 职场文书
员工拾金不昧表扬信
2014/01/09 职场文书
婚礼证婚人证婚词
2014/01/13 职场文书
学习自我鉴定
2014/02/01 职场文书
企业晚会策划方案
2014/05/29 职场文书
2014年仓库管理工作总结
2014/12/17 职场文书
优秀党支部申报材料
2014/12/24 职场文书
2016年寒假社会实践活动心得体会
2015/10/09 职场文书
《王者天下》第4季首话新剧照 4月9日正式开播
2022/04/07 日漫