KnockoutJS 实例

最近开始用KnockoutJS 作为client的主要框架,结合Bootstrap, BootstrapValidator, 直接调用Web api,绕过MVC的controller那层来交互数据,效果非常不错,项目做到现在进度一半,knockout的优点很多,所以这里小结一下:

 

 

Q: 什么是KnockoutJS?

A: 我们都叫它KO, 一个基于MVVM架构的轻量级JavaScript框架,最大的特点就是支持界面Dom对象和JS 数据对象的双向绑定。

 

 

Q:KO的优点?

  • 免费,使用MIT开源软件许可协议
  • 纯JavaScript, 可以和任何其他框架一起工作,没有依赖
  • 轻量级框架, 相对于AugularJS, jQuery,压缩后只有20kb
  • 已经比较成熟,支持IE6+, Firefox     3.5+, Chrome, Opera, Safari等浏览器
  • KO做的事情j比如Query也能做,但是比较麻烦,有很多代码需要写,而且不够直观; AugularJS也能做,但是比较复杂,学习成本较高。

 接下来,我们来了解下如何完成一个KO的页面:

  1. 数据

KO提供了灵活的方式支持对JS的对象定义在View Model,然后绑定到HTML元素上,View Model里面的值和 HTML上面的元素相匹配。

  1. 声明普通JS 对象来定义View Model对象
varmyViewModel = {
    personName:'Bob',
    personAge: ko.observable(123),
    jobs:ko.observableArray("Engineer", "Tester")
};

varContactsModel = function (contacts) {
       var self = this;
       self.FirstName = "King";
       self.LastName =ko.observable("");
       self.Id = "";
}

Note:

  1. 普通的赋值适用于值不变的对象,适用于Lable等
  2. Observable代表双向绑定,也就是界面的DOM对象更新,这个JS变量也会跟着更新, 一般的input需要定义成这种对象。
  3. ObservableArray对应数组的双向绑定,适用对Checkbox等多选的对象。

 

      b. 声明JSON为View Model对象

   var initialData = [
        {
            firstName: "Danny",lastName: "LaRusso",id:"C6A2D391-6B68-42EA-9EE2-3E25756143C2", phones: [
              { type: "Mobile",number: "(555) 121-2121", id:"C6A2D391-6B68-42EA-9EE2-3E25756143C1" },
              { type: "Home", number:"(555) 123-4567", id:"C6A2D391-6B68-42EA-9EE2-3E25756143C5" }]
        },
        {
            firstName: "Sensei",lastName: "Miyagi", id:"C6A2D391-6B68-42EA-9EE2-3E2575614334", phones: [
              { type: "Mobile",number: "(555) 444-2222", id:"C6A2D391-6B68-42EA-9EE2-3E25756143C20" },
              { type: "Home", number:"(555) 999-1212", id:"C6A2D391-6B67-42EA-9EE2-3E25756143C2" }]
        }
    ];

 
    var ContactsModel = function (contacts) {
        var self = this;
        self.contacts =ko.observableArray(ko.utils.arrayMap(contacts, function (contact) {
            return {
               firstName:ko.observable(contact.firstName),
                lastName:ko.observable(contact.lastName),
                id: contact.id,
                phones:ko.observableArray(ko.utils.arrayMap(contact.phones, function (phone) {
                   return {
                        type2:ko.observable(phone.type),
                        number2:ko.observable(phone.number),
                        id: phone.id
                    }
                }))
            };
        }));
}

 

KO提供了Ko.utils类库来支持一些基本的操作,比如ko.utils.arrayMap相当于$.each,可以对数组里面的对象逐个绑,在多层结构的JSON或数据非常有用。这种方式相当于手动绑定JSON对象里面的元素,可以过滤掉不用的,也可以重命名。如果整个JSON都需要用,不需要过滤,而且不需要重命名,可以用KO的Mapping插件,非常方便。一开始不知道有这个Mapping插件,写了很多手动匹配的代码。。。

  1. 数据绑定

定义好数据,接下来就是绑定到HTML作用域了。使用applyBindings方法,第一个参数是ViewModel,第二个参数是HTML的节点,这里注意下,如果第二个参数不指定或指定的DOM对象不存在,都会绑定为全局的作用域。 

 ko.applyBindings(newContactsModel(initialData), document.getElementById("contactsList"));
  1. HTML  View层

这也是KO的核心部分之一,KO定义了很多常用的Bindings,针对HTML 标签,属性,CSS样式,事件,所有的绑定行为写在Data-bind属性里,也可以写在注释<!-- -->里(这个非常有用)。有了View层的binding, 所有的逻辑都能够很显式的在HTML里找到,enable/disable,visible/invisible, click/textInput, if/ifnot等等,比起jQuery把所有的行为写在js里,HTML完全看不出来有哪些逻辑直观很多。

<divid='contactsList'>
    <table class='contactsEditor'>
       <thead>
            <tr>
                <td>First name</td>
                <td>Last name</td>
                <td>Operation</td>

        </thead>
        <tbodydata-bind="foreach: contacts">  <!-- foreach 绑定-->
           <tr>
                <td><inputdata-bind="value: firstName" class="form-control" />   <!-- value 绑定-->
                </td>
                <td><inputdata-bind='value: lastName' class="form-control" /></td>
                <td>
                    <buttonclass="btn btn-warning" data-toggle="modal"data-target="#updateContact" data-bind="click:$root.updateContactInit.bind(this,firstName,lastName,id)">Update acontact</button>    <!-- click事件绑定-->
                    <buttondata-bind='click: $root.removeContact' class="btnbtn-warning">Delete Contact</button>
                </td>
             </tr>
        </tbody>
    </table>
</div>

 

Binding的使用在KO的官网都有解释 http://knockoutjs.com/documentation/introduction.html, 个人觉得比Tom大叔讲的要明白很多。

Note:

  1. click: $root.removeContact, 这个绑定会把当前层的Ko对象作为参数传递给removeContact方法,如果想要传递多个参数,可以使用bind方法,例如$root.updateContactInit.bind(this,firstName,lastName,id)
  2. checked绑定对于checkbox非常有用,只需声明个数组 this.checkedList= ko.observableArray(); 然后在HTML绑定时指定value和checked就能实现多选,不需要很复杂的代码:databind="value: Id, checked: checkedList", checkedList取到的就是选中的Id列表。
  3. Input标签使用textInput 绑定而不是value, textInput在值改变的时候就能触发, value要等到keydown才行。

 

最后就是KO的一个带2层数据的CRUD例子,官网上的例子是直接在input里修改,实际项目很少这么做,一般都是弹出框修改,所以我把它改成了bootstrap的popupmodel:http://jsbin.com/bahofu/ ,里面的updatePhone方法留给大家思考。

 

Reference:

http://blog.nebithi.com/knockoutjs-vs-angularjs/

http://knockoutjs.com/documentation/introduction.html

http://knockoutjs.com/examples/

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值