knockoutJS学习笔记04:监控属性

时间:2023-03-08 16:42:59

一、语法介绍

  先来看一个简单的例子:

  <span data-bind="text:name"></span>

  var obj = {name:ko.observable("tom")}

  ko.applyBindings(obj);

  这样会自动完成绑定。其中有3个特别的地方:1. data-bind。2.ko.observable 方法。 3.ko.applyBindings 方法。

1.1 data-bind

  data-bind 并不是html元素的固有属性,但它是完全正确的(符合html5规范),虽然在非html5验证器中会提示这是一个无效的属性,但这不会有任何问题。ko就是用data-bind来声明绑定的。

  data-bind 依赖于标签,也就是data-bind必须作为标签属性写在标签内。所以我们要输出一个变量,也必须绑定在标签内才能输出。

  例如:data-bind="text:name",text 是我们要绑定的“属性”,例如要为 span、div 赋值,就用 text;这个与jquery 的写法是一样的,例如我们会用 $("#id").text(str); 如果是一个编辑框呢?就是 value:name 了。

  这里有一个小小的建议,很多时候我们会在标签里自定义属性,例如userid,建议都用 data- 开头,例如:data-userid。

1.2 observable

  有了视图,还要数据。如过上面属性直接写为: name:"tom",也是可以完成绑定的。不过这样就只是单向、一次性绑定了。如果要进行双向绑定,就要用 observable方法了,用了该方法后,该属性就不是简单的js对象属性了,而是ko特有的对象,取值和赋值也都跟普通属性不一样了。

1.3 applyBindings

  有了视图和数据,只需要触发绑定操作就ok了。ko的applyBindings 方法就是触发绑定的,它有2个参数,第一个参数是数据对象,第二个参数是可选的,用来设置使用 data-bind 的html元素或容器。例如,有时候界面上有很多处绑定,为了让结构更加清晰和避免冲突,可以用:ko.applyBindings(obj,document.getElementById("list")); 这样就表示obj对象绑定在id为list内,声明有 data-bind 的html元素。

了解了ko的绑定方式后,我们来总结一下数据绑定的几种方式:

一般的数据绑定有三种:One-Time,One-Way,Two-way。

One-Time绑定模式:从viewModel绑定至UI这一层只进行一次绑定,程序不会继续追踪数据的在两者中任何一方的变化,这种绑定方式适用于数据仅仅会加载一次的情况。

One-Way绑定模式:单向绑定,即object-UI的绑定,只有当viewModel中数据发生了变化,UI中的数据也将会随之发生变化,反之不然。

Two-Way绑定模式:双向绑定,无论数据在Object或者是UI中发生变化,应用程序将会更新另一方,这是最为灵活的绑定方式,同时代价也是最大的。

数据绑定只是作为元素的自定义属性写上标签内,并不能决定它是何种绑定。

如果值是通过ko.observable定义的说明是双向绑定,否则为One-Time绑定,在knockout不存在单向绑定。

二、监控属性的取值/赋值

2.1 取值

  上面说到observable属性不再是普通属性,它的取值也不再是obj.name这样的格式了,而是通过 obj.name() 这样获得,实际上我们可以将 name 打印出来,它已经变成一个函数了。

2.2 赋值

  同理,赋值不能用 obj.name = "xxx",而是用 obj.name("xxx"); 这种取值和赋值的方法设计和jquery的设计是一样的。而且,这里也可以链式调用,例如:obj.name("xxx").age("20");

2.3 例子

  接下来就通过一个例子来体会双向绑定。当编辑框失去焦点时,右边的自动更新,点击清空恢复原状。这个过程没有用到dom操作。

  knockoutJS学习笔记04:监控属性

  html:  

    <p>姓名:<input type="text" data-bind="value:name" /> 您输入的姓名:<span data-bind="text:name"></span></p>
<p>年龄:<input type="text" data-bind="value:age" /> 您输入的姓名:<span data-bind="text:age"></span></p>
<p><input type="button" value="清空" onclick="reset()" /></p>

  js:  

    var obj = {
name : ko.observable(""),
age : ko.observable(0)
}
ko.applyBindings(obj);
function reset(){
obj.name("");
obj.age(0);
}

三、compute

  计算属性。熟悉数据库的朋友应该了解有个字段叫做【计算字段】,顾名思义,这个字段的值是由其它字段计算而来的。ko里的计算属性也是一样的,由其它属性计算而来,具体计算方式由我们控制。例如上面的例子,我们想在输入姓名和年龄后自动完成:“姓名,年龄” 这样的格式就可以用计算属性。如:

<p>总信息:<span data-bind="text:format"></span></p>

  这里把数据改为 function 的写法,因为在js里函数也是对象,这也是一种推荐的写法。  

    function Person(){
this.name = ko.observable("");
this.age = ko.observable(0);
this.format = ko.computed(function(){
return this.name() + "," + this.age();
},this);
}
var person = new Person();
ko.applyBindings(person);
function reset(){
person.name("");
person.age(0);
}

  这里要注意的是 this 是作为 computed 的参数传入。因为我们要获得Person对象的name和age属性,而传入的this,经调用构造函数后,就指向了Person对象。如果没有这样传入呢?那么this指向的是window对象。关于this 的用法也可以看这篇文章:我这样理解js里的this。

  另外,计算属性还支持下面的写法,支持更复杂的操作,不过一般很少用到。如下:

        this.format = ko.computed({
read:function(){return this.name() + "," + this.age;},
write:function(value){console.log(value);},
owner:this
});

四、总结

  observable 是ko 的核心之一,是它在对象的属性和dom之间建立了绑定。