本文是【Knockout.js 学习体验之旅】系列文章的第2篇,全部demo均基于目前knockout.js的最新版本(3.4.0)。小茄才识有限,文中如有不当之处,还望你们指出。javascript
目录: css
【Knockout.js 学习体验之旅】(1)ko初体验html
【Knockout.js 学习体验之旅】(2)花式捆绑java
提到捆绑,相信不少邪恶的筒子觉得小茄第一时间想到的是:数组
然而,并无!浏览器
小茄第一时间想到的是 data-bind = "value: price",data-bind = "text: sum",data-bind = "XX: OO"……(好吧,这有点用力过猛了)app
言归正传,在上一篇文章(【Knockoutjs 学习体验之旅】(1)ko初体验)中提到,ko中的 data-bind = "XX:OO"绑定大法除了能够绑定text、value等内容,还能够绑定visible、style等外观属性,也能够绑定click、textInput等各类事件,甚至还能控制程序流程。各类花式捆绑,绝对知足你的幻想。ide
下面简单讲讲各类绑定的使用,主要根据被绑定的属性分红表现类、流程类和交互类三种。函数
表现类的绑定属性有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
效果是这样的:
上一篇文章里面也说过,XXOO里面除了传单个的属性,也能够传JSON对象,也就是说能够组合绑定属性,好比说:
<!--HTML code--> <div data-bind="{visible: shouldShowMessage, text: myMessage, css: { profitWarning: currentProfit() < 0 }}"> You will see this message only when "shouldShowMessage" holds a true value. </div>
效果固然是这样的:
表现类的设置比较简单,要注意的一点就是:不少表现类的属性并不须要动态变化,这个时候能够利用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只是控制隐藏显示(注意是增减display: none,而不是CSS里面的visible),组件仍是在DOM里面的。with 跟 js 中的 with 也是同样的效果,就是延长了做用域链,简单的来讲就是在变量前加了个’前缀.’。这里只介绍一下foreach,component放到和模板绑定一块儿介绍。
看看代码:
<!--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 (右)是立刻进行更新的。
虽然,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:
Click the name to edit it; click elsewhere to apply changes.
点击上面的姓名就能够变成可编辑状态,失去焦点后又变成普通文字,这种效果用ko实现起来至关简单。
本篇主要简单介绍了knockoutjs中各类绑定的使用方法,使用这些绑定方法的组合就能简单地作好一个须要较多动态交互的UI页面。使用这些方法比较重要的一点就是要记住绑定的都是函数对象,因此能够直接在HTML里面进行操做,这样的话有时候 js 代码结构能够更简单。
关于绑定的介绍就到这里了,下一篇再见。码字不易,随手点赞哈~~~
参考资料:
文字较多,惯例凑图!
原创文章,转载请注明出处!本文连接:http://www.cnblogs.com/qieguo/p/5563254.html