在上一篇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
效果是这样的:
上一篇文章里面也说过,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只是控制隐藏显示,组件还是在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());