代码改变世界

Javascript MVVM模式前端框架—Knockout 2.1.0系列(1):初识Ko,了解Observable与computed

2012-05-17 17:31  刺客之家  阅读(5755)  评论(20编辑  收藏  举报

*本文已经同步至索引目录:http://www.cnblogs.com/wbpmrck/archive/2012/05/16/Knockout-introduction.html

KO是什么?

KO不是万能的,它的出现主要是为了方便的解决下面的问题:

  • UI元素较多,用户交互比较频繁,需要编写大量的手工代码维护UI元素的状态、样式等属性?
  • UI元素之间关系比较紧密,比如操作一个元素,需要改变另外一个元素的状态?
  • DOM元素与Js对象之间的数据同步?
  • 前端javascript代码组织不理想?用户输入数据校验、DOM操作、后台交互…,交织在一起?

基础概念一:viewModel

  • 负责处理UI事件的响应,响应用户操作。
  • 负责保存领域模型在前端的变体Model’,比如:Student模型,在UI元素与Model之间同步数据(用户修改input-->ko修改model,反之亦然)
  • 在需要的时候,可以使用Helper方法轻松地从viewModel中剥离出需要传递给Server的数据,通过ajax方式与后台交互。
  • 负责接收Server端发送过来的数据(可能是Ajax请求),更新模型数据,同时更新UI展现。

基础概念二:Observable与computed

纵观KO的所有应用场景,基本上这2个属性至少会用到一个。个人认为这是KO最常使用的东西。他们用法如下:

  • Observable(监控属性):监控自身属性的变化,向外部发送通知。外部通过subscribe方法来订阅属性的变化事件。
  • Computed(依赖属性):在早期版本中叫做dependentObservable,它通常依赖于其他的Observable,通过计算得出自己的数据。当依赖项改变的时候,computed属性会接到通知,然后同步更新自身

*这里提2点:

  • 虽然本文称之为“属性”,但是本质上他们是js的function对象,所以访问的时候需要加()号
  • 默认情况下Computed的同步发生在任意的Observable变化的时候,可是某些情况下我们可能不希望它更新的如此频繁,比如用户正在输入的过程中。KO有其他办法来延迟更新,在本系列后面会有专门文章介绍。

本章的重点就是讲解这2个基本属性的用法,在后面的“实例讲解”中会详细说明。

如何激活KO绑定

KO中,绑定是需要激活的,可以理解为把viewModel的数据与Html文档的DOM元素进行分析和关联

通常是在页面元素、viewModel数据加载完毕之后,就可以激活绑定了。当然你可以在任何时候你想进行绑定的时候来激活。

只需要下面的代码:

 var model = new AppViewModel();//实例化一个viewModel
 ko.applyBindings(model); //绑定到整个页面

这样KO会在整个Body中寻找需要进行绑定的元素,与viewModel进行绑定。当然你也可以指定绑定的根节点,这样的好处:

  1. 可以缩小KO查找绑定的范围(毕竟不是整个页面都需要进行binding)
  2. 可以同时使用多个viewModel,分别负责不同区域的绑定(是不是你想要的?haha…)

很简单,加一个参数即可:

var model = new AppViewModel();
ko.applyBindings(model, document.getElementById("Demo1")); //Demo1可能是一个Div

 

实例讲解:Observable

基本语法

1、定义

var myViewModel = {
    personName: ko.observable('Bob'),//定义叫做personName的监控属性
    personAge: ko.observable(123)//定义叫做personAge的监控属性
};

2、读取

var a=myViewModel.personName();//a为'Bob'

3、写入、连续写入(链式调用)

myViewModel.personName('Mary').personAge(50);//同时修改了2个属性值

 4、订阅属性修改事件

myViewModel.personName.subscribe(function(newValue) {
    alert("The person's new name is " + newValue);
});

myViewModel.personName('换个名字');//这时候会弹出alert

Demo

http://jsfiddle.net/wbpmrck/LkTxp/69/embedded/

看不到内嵌Demo的点这里查看在线Demo

(如果大家可以看到内嵌Demo,直接点击Result或者向右小三角看结果)

 ps:

  1. 折腾了半天才绕过了博客园对iframe的过滤,如果个别童鞋看不到demo,请点击上面的链接看demo~
  2. demo中为了演示功能,提前使用了后面会说到的click绑定,原因是我发现jsFiddle网站上用onclick绑定本地js函数无法访问。如果有哪位知道的麻烦告知一下,谢谢!
  3. 大家只需关注点击处理函数中如何读取和修改observable的部分即可

实例讲解:Computed

在上面例子中,我们有2个属性firstName和lastName,但是如果我们想显示一个全名,并且希望这个全名可以根据firstName和lastName的变化而变化,怎么办?下面Computed登场!

基本语法

1、定义Computed属性

function AppViewModel() {
    var self = this;
 
    self.firstName = ko.observable('Bob');
    self.lastName = ko.observable('Smith');     
   //下面这个属性依赖上面的2个属性存在
    self.fullName = ko.computed(function() {
        return self.firstName() + " " + self.lastName();
    });
}

2、读取Computed属性

var model = new AppViewModel();
var full =model.fullName();//full="Bob Smith"

Demo

http://jsfiddle.net/wbpmrck/hb8HD/14/embedded/

 看不到内嵌Demo的点这里查看在线Demo

说明:

为了演示方便,这里提前使用了text绑定和value绑定来显示viewModel属性的值,这个绑定很好理解,后面会说到

到这里,大家可能已经感觉到computed比较特殊,他是动态计算的,那么如果要“修改”computed怎么做?看下面。

高级语法

1、可‘写’的Computed

this.fullName = ko.computed({
        //调用fullName()读取时,会执行这里
        read: function () {
            return this.firstName() + " " + this.lastName(); 
        },
        //调用fullName('xx')写入时,会执行这里
        write: function (value) {
            var lastSpacePos = value.lastIndexOf(" ");
            if (lastSpacePos > 0) { // Ignore values with no space character
                this.firstName(value.substring(0, lastSpacePos)); // Update "firstName"
                this.lastName(value.substring(lastSpacePos + 1)); // Update "lastName"
            }
        },
        //传入一个对象,该对象作为this指针在read,write方法中使用
        owner: this
    });

语法说明:

  1. read属性:自定义函数,该函数的返回值就是调用fullName()获取computed属性值时得到的结果
  2. write属性:自定义函数,该函数通过修改依赖项firstName和lastName来修改自身
  3. owner属性:传入对象,该对象作为this关键字在read和write方法中使用(函数的调用对象,不明白的童鞋回去看看js基础...)

Demo

http://jsfiddle.net/wbpmrck/hb8HD/21/embedded/

 看不到内嵌Demo的点这里查看在线Demo

总结

本文主要介绍了ko中的observable和computed用法,它们是ko的核心组件,也是实现依赖跟踪的关键点。

感谢支持

如果本文对您有帮助的话,请别吝啬手中的推荐票哦~

本博客文章若非标记转载,均为原创,转载请注明出处~