首页 > 代码库 > knockout简单实用教程2

knockout简单实用教程2

在上一篇文章中简单了介绍了下什么ko(后文中都已ko来代替knockout.js)和一些简单的ko的使用方法下面我将介绍在实际的项目中常用到的几种绑定方式和方法.

在开始之前先拿一个dome来回顾下ko的绑定方式吧。废话不多说上代码。

var BetterListModel = function () {    this.itemToAdd = ko.observable("");    this.allItems = ko.observableArray(["Fries", "Eggs Benedict", "Ham", "Cheese"]); // 初始化数据    this.selectedItems = ko.observableArray(["Ham"]);                                // 初始化选定项     this.addItem = function () {        if ((this.itemToAdd() != "") && (this.allItems.indexOf(this.itemToAdd()) < 0)) // 判断不为空并且不存在重复的数据            this.allItems.push(this.itemToAdd());        this.itemToAdd(""); // 清空文本框内容绑定    };     this.removeSelected = function () {        this.allItems.removeAll(this.selectedItems());        this.selectedItems([]); //清空集合    };     this.sortItems = function() {        this.allItems.sort();    };}; ko.applyBindings(new BetterListModel());

简单说明下。创建了一个对象模型。里面有一些简单属性和复杂属性,还有一个行为事件(以面向对象来理解会很简单) 如果看过之前的文章在看这个相信会一目了然.

下面给出dom的绑定

<form data-bind="submit:addItem">    Add item: <input type="text" data-bind=‘value:itemToAdd, valueUpdate: "afterkeydown"‘ />    <button type="submit" data-bind="enable: itemToAdd().length > 0">Add</button></form> <p>Your values:</p><select multiple="multiple" height="5" data-bind="options:allItems, selectedOptions:selectedItems"> </select> <div>    <button data-bind="click: removeSelected, enable: selectedItems().length > 0">Remove</button>    <button data-bind="click: sortItems, enable: allItems().length > 1">Sort</button></div>

照例也给出调试的地址 http://jsfiddle.net/rniemeyer/aDahT/   

 

上面的内容呢主要还是用来回顾之前的东西。下面开始本节的内容。先从表单的绑定说起吧。先直接给出来表单模型的定义代码

var viewModel = {    stringValue : ko.observable("Hello"),    passwordValue : ko.observable("mypass"),    booleanValue : ko.observable(true),    optionValues : ["Alpha", "Beta", "Gamma"],    selectedOptionValue : ko.observable("Gamma"),    multipleSelectedOptionValues : ko.observable(["Alpha"]),    radioSelectedOptionValue : ko.observable("Beta")};ko.applyBindings(viewModel);

上面的模型定了基本都是定一些了些属性和一些默认值,当然你也可以动态的从后台拿到这个数据,然后直接更新对象的模型属性即可,像这样   viewModel.optionValues(youdata) 

下面继续说前台的绑定,这里先直接给出绑定的代码。

<div class="readout">    <h3>What‘s in the model?</h3>    <table>        <tr>            <td class="label">Text value:</td>            <td data-bind="text: stringValue"></td>        </tr>        <tr>            <td class="label">Password:</td>            <td data-bind="text: passwordValue"></td>        </tr>        <tr>            <td class="label">Bool value:</td>            <td data-bind=‘text: booleanValue() ? "True" : "False"‘></td>        </tr>        <tr>            <td class="label">Selected option:</td>            <td data-bind="text: selectedOptionValue"></td>        </tr>        <tr>            <td class="label">Multi-selected options:</td>            <td data-bind="text: multipleSelectedOptionValues"></td>        </tr>        <tr>            <td class="label">Radio button selection:</td>            <td data-bind="text: radioSelectedOptionValue"></td>        </tr>    </table></div> <h3>HTML controls</h3><table>    <tr>        <td class="label">Text value (updates on change):</td>        <td><input data-bind="value: stringValue" /></td>    </tr>    <tr>        <td class="label">Text value (updates on keystroke):</td>        <td><input data-bind=‘value: stringValue, valueUpdate: "afterkeydown"‘ /></td>    </tr>    <tr>        <td class="label">Text value (multi-line):</td>        <td><textarea data-bind="value: stringValue"> </textarea></td>    </tr>    <tr>        <td class="label">Password:</td>        <td><input type="password" data-bind="value: passwordValue" /></td>    </tr>    <tr>        <td class="label">Checkbox:</td>        <td><input type="checkbox" data-bind="checked: booleanValue" /></td>    </tr>    <tr>        <td class="label">Drop-down list:</td>        <td><select data-bind="options: optionValues, value: selectedOptionValue"></select></td>    </tr>    <tr>        <td class="label">Multi-select drop-down list:</td>        <td><select multiple="multiple" data-bind="options: optionValues, selectedOptions: multipleSelectedOptionValues"></select></td>    </tr>    <tr>        <td class="label">Radio buttons:</td>        <td>            <label><input type="radio" value="Alpha" data-bind="checked: radioSelectedOptionValue" />Alpha</label>            <label><input type="radio" value="Beta" data-bind="checked: radioSelectedOptionValue" />Beta</label>            <label><input type="radio" value="Gamma" data-bind="checked: radioSelectedOptionValue" />Gamma</label>        </td>    </tr></table>

调试的地址为 http://jsfiddle.net/rniemeyer/ZbrB7/

在这我就详细说明下具体的绑定到底是什么代表什么意思。其实大家应该从字面上都可以简单的看出来这些绑定是干什么的。但是为了让初学者看的更明白些,我还是准备说明一下。

1:data-bind="text:你要绑定的字段名称" //这里绑定是指的显示的文本信息的绑定.

2:data-bind="value:你要绑定的字段名称"//文本框值的绑定.

3:data-bind="checked:true或者false或者是表达式"//这个绑定是针对单选和多选框的绑定方法。用来指明是否被选中.

4:data-bind="options:选项的集合,selectedOptions:默认选中的值"//绑定select的options ,selectedOptions用来指定默认选中的值.

上面的4种绑定方式呢,是比较常用的表单元素的绑定,PS:(如果你需要用表达式动态绑定的时候,你需要在要判断的元素后面加上小括号).在这里我提一个问题。如果需要通过一个判定字段来判断后面的内容是否绑定要怎么做?这里我先卖个关子,你们可以先思考下,后面我会给出说明,如果在后面的dome中如果出现新的绑定方式我会再次说明.

    <td data-bind=‘text: booleanValue() ? "True" : "False"‘></td>

下面继续介绍如何绑定数据集合的绑定。也顺便引出新的绑定方式foreach绑定。

// 定义一个人的对象。这个对象有两个字段 一个是名字一个是子节点 默认有两个构造函数的参数.var Person = function(name, children) {    this.name = name;    this.children = ko.observableArray(children);     this.addChild = function() {        this.children.push("New child");    }.bind(this);} // 在定义一个页面UI的模型对象,模型对象people里面放入person集合var viewModel = {    people: [        new Person("Annabelle", ["Arnie", "Anders", "Apple"]),        new Person("Bertie", ["Boutros-Boutros", "Brianna", "Barbie", "Bee-bop"]),        new Person("Charles", ["Cayenne", "Cleopatra"])        ],    showRenderTimes: ko.observable(false)}; ko.applyBindings(viewModel);

这里直接给出dom绑定下面在说明

<h2>People</h2><ul data-bind="foreach: people">    <li>        <div>            <span data-bind="text: name"> </span> has <span data-bind=‘text: children().length‘>&nbsp;</span> children:            <a href=‘#‘ data-bind=‘click: addChild ‘>Add child</a>            <span class=‘renderTime‘ data-bind=‘visible: $root.showRenderTimes‘>                (person rendered at <span data-bind=‘text: new Date().getSeconds()‘ > </span>)            </span>        </div>        <ul data-bind="foreach: children">            <li>                <span data-bind="text: $data"> </span>                <span class=‘renderTime‘ data-bind=‘visible: $root.showRenderTimes‘>                    (child rendered at <span data-bind=‘text: new Date().getSeconds()‘ > </span>)                </span>            </li>        </ul>    </li></ul><label><input data-bind=‘checked: showRenderTimes‘ type=‘checkbox‘ /> Show render times</label> 

调试的 地址是 http://jsfiddle.net/rniemeyer/GSvnh/

 

这里的data-bind="foreach:你要循环的集合"//在foreach包裹的区域内。你可以绑定对应的单个对象的具体字段内容。如果里面里面的某一个字段是一个集合你还可以继续嵌套循环来绑定数据如上,PS( 这里顺便说一嘴。就是说如果你需要在子循环里面,绑定父循环的数据你需要像这样来绑定,$.parent.父节点字段) 上面代表中出现的$.data就代表当前的绑定对象本身,而$.root则代表模型里面最高层对象.

这里的foreach 绑定也就是用的最多的绑定,用起来也很简单,但是它有一个问题,就是他的绑定需要指定一个父容器也就是说要绑到具体的dom元素上,但是有时候我并不想绑定到具体的dom对象上哪怎么办呢?。那就没办法解决吗? 

答案当然是否定的。KO官方给出 了比较另类但是很实用的的绑定方式用来解决这个问题,我觉得这算是一个语法糖了。

就以上面的绑定为例,你可以这么写 

<div class=‘liveExample‘>         <h2>People</h2>    <!--ko foreach:people-->        <li>            <div>                <span data-bind="text: name"> </span> has <span data-bind=‘text: children().length‘>&nbsp;</span> children:                <a href=‘#‘ data-bind=‘click: addChild ‘>Add child</a>                <span class=‘renderTime‘ data-bind=‘visible: $root.showRenderTimes‘>                    (person rendered at <span data-bind=‘text: new Date().getSeconds()‘ > </span>)                </span>            </div>            <ul data-bind="foreach: children">                <li>                    <span data-bind="text: $data"> </span>                    <span class=‘renderTime‘ data-bind=‘visible: $root.showRenderTimes‘>                        (child rendered at <span data-bind=‘text: new Date().getSeconds()‘ > </span>)                    </span>                </li>            </ul>        </li>          <!--/ko-->    <label><input data-bind=‘checked: showRenderTimes‘ type=‘checkbox‘ /> Show render times</label>     </div>

相信大家一看就能明白上面代码的意思。只是把对应的<ul data-bind="foreach: people"> </ul>绑定具体的dom元素换成了看起来像注释的绑定方式 <!--foreach:people--><!--/ko-->,两种绑定方式的效果是一样的,但是第二种绑定方式我比较推荐。因为它用起来会更加的灵活多变。

在这我在顺便回答下,上面我提成的问题。也就是如何通过绑定的字段判断后面的内容是否需要绑定呢?下面给出代码

<ul data-bind="foreach: planets">    <li>        Planet: <b data-bind="text: name"> </b>        <div data-bind="if: capital">            Capital: <b data-bind="text: capital.cityName"> </b>        </div>    </li></ul>  <script>    ko.applyBindings({        planets: [            { name: Mercury, capital: null },             { name: Earth, capital: { cityName: Barnsley } }                ]    });</script>

在data-bind中有个if的绑定方式。我们可以用这个来解决我刚才说过的问题。与之对应的还有另一种绑定方法就是ifnot 下面给出代码大家可以对照着理解

<div data-bind="ifnot: someProperty">...</div>

看到这,我相信你已经理解的ko的基本使用的方法,现在你可以在你的项目中使用KO来绑定数据了。

 

关于更多细枝末节的问题呢我会继续在后面的章节里来说明。

 

 

 

 

 

 

 

 

knockout简单实用教程2