<!--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 codevar viewModel = {shouldShowMessage: ko.observable(true), // Message initially visiblemyMessage: ko.observable(), // Initially blankdetails: ko.observable(), // Initially blankcurrentProfit: ko.observable(150000), // Positive value, so initially we don"t apply the "profitWarning" classcurrentProfit: ko.observable(150000), // Positive value, so initially blackurl: 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 codevar viewModel = {shouldShowMessage: ko.observable(true), // Message initially visiblemyMessage: "这段文字不需要动态更新" // Initially blank}; 流程类属性
看看代码:
<!--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这些变量,按字面意思理解即可。<button data-bind="click: function(data, event) { myFunction("param1", "param2", data, event) }">Click me</button> 2. 默认行为的设置(比如链接)<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绑定

虽然,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 propertiesvar 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来绑定选中项目。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