【Knockout】二、监控属性Observables
MVVM和viewModel
Knockout是建立在以下三大核心功能之上的:
- 监控属性和依赖跟踪(Observables and dependency tracking)
- 声明式绑定(Declarative bindings)
- 模板(Templating)
首先让我们先来了解下MVVM模式,和viewModel的概念。
MVVM(model、view、viewModel)是一种创建用户界面的设计模式,他旨在将一个复杂的UI简单的分割为三个部分:
- model : 在你的应用用作存储数据;
- view : 一个可见的、交互的UI来展现viewModel的状态;
- viewModel : 用纯净的代码来展现ui的数据和操作,可是任意的javascript对象
首先创建一个viewModel,仅仅需要声明一个任意的javascript对象,例如:
var viewModel = {
name : 'knockout'
};
然后为viewModel创建一个声明式的绑定view,例如:
<div id="myview" data-bind="text : name"></div>
最后激活knockout,例如
ko.applyBindings(viewModel,document.getElementById('myview'));
data-bind属性毕竟不是原生的html属性,即使它能够完美的工作,但是浏览器不认识它,你需要激活knockout使它生效。
这样就把一个最简单的viewModel和view绑定到了一起,能够在view里显示viewModel的属性name了,但是,view却不能再viewModel改变的时候自动更新,viewModel也不能再view改变是自动更新!
Observables
knockout的一个重要功能observable(监控属性)就是能够自动自动探测相关的依赖与通知订阅者(automatic dependency detection and notification triggering),即在建立绑定关系的view和
viewModel之间能够在一方改变的时候更新另一方的值。
我们将viewModel稍作修改:
var viewModel = {
name : ko.observable("knockout")
};
现在他就能监控到变化,view就能够自动更新了。
监控属性的读写操作:
1.读取监控属性的值:
viewModel.name();
2.写一个新值到监控属性中:
viewModel.name("new value");
Observable Arrays
如果你想探测并响应一个对象的变化,使用observables,但是,如果你想探测并响应一系列集合的变化,你应该使用observableArray。
当你需要重复的增加或者删除时需要显示或者隐藏一些UI的区域时,observableArray能够派上大用场。
var myObservableArray = ko.observableArray(); // Initially an empty array
myObservableArray.push('Some value'); // Adds the value and notifies observers
注:observableArray跟踪的是数组中的对象,而不是对象的状态。单纯的push一个对象到observableArray中,这个对象的属性并不是observable的,observableArray仅仅跟踪它所拥有的对象,并当有对象从数组中添加或删除时通知监听者。
也可以像这样初始化一个observableArray:
// This observable array initially contains three objects
var anotherObservableArray = ko.observableArray([
{ name: "Bungle", type: "Bear" },
{ name: "George", type: "Hippo" },
{ name: "Zippy", type: "Unknown" }
]);
Computed Observables (依赖监控属性)
如果你有一个observable的firstname和一个observable的lastname,你想显示fullname怎么办?computed observables派上用场了,它是一个依赖于其他一个或者多个observables的函数,并在任意一个依赖的observable更新时它能够自动更新。
例如:有这样一个viewModel:
function AppViewModel() {
this.firstName = ko.observable('Bob');
this.lastName = ko.observable('Smith');
}
你可以添加一个computed observable来得到fullname:
function AppViewModel() {
// ... leave firstName and lastName unchanged ... this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}
绑定UI元素:
The name is <span data-bind="text: fullName"></span>
当firstname或者lastname改变时fullname能够自动更新。
你可以这样使用:
- 监控属性items表示items的集合;
- 监控属性selectedIndexes存储当前选中的items的index集合;
- 依赖监控属性selectedItems表示当前选中的items集合;
改变items或者selectedIndexes都能够使依赖监控属性(selectedItems)更新,以达到更新相应的UI元素的目的。
管理this :
ko.computed的第二个参数决定了this的值当我们计算依赖监控属性的值的时候,如果不传它,将不能够引用到this.firstname()或者this.lastname().
你也可以这样做,更加方便:
function AppViewModel() {
var self = this; self.firstName = ko.observable('Bob');
self.lastName = ko.observable('Smith');
self.fullName = ko.computed(function() {
return self.firstName() + " " + self.lastName();
});
}
self能够在funciton的闭包中被捕获到,在它任何的内嵌的function中任然是可用的。
判断一个属性是否为依赖监控属性(computed observable)
for (var prop in myObject) {
if (myObject.hasOwnProperty(prop) && !ko.isComputed(myObject[prop])) {
result[prop] = myObject[prop];
}
}
另外,ko提供了一些函数能够操作监控属性和依赖监控属性:
- ko.isObservable : 对于所有的observable,observable array,computed observable将返回true;
- ko.isWritableObservable : 对于所有的observable,observable array,writable computed observable返回true;
使用peek控制依赖关系:
正常情况下,ko的自动依赖跟踪能够完成你所期望的工作,但是,你也许希望控制哪个observable来更新或者不更新你的computed observable,peek()函数能够使你的observable或者computed不创建依赖关系。
例如:
ko.computed(function() {
var params = {
page: this.pageIndex(),
selected: this.selectedItem.peek()
};
$.getJSON('/Some/Json/Service', params, this.currentPageData);
}, this);
在这个例子中,一个computed observable依赖其他两个observable使用ajax获取数据,当pageIndex改变的时候,computed observable就会更新,重新获取数据,但是computed observable会忽略掉selectedItem的改变,
因为它使用了peek()。在这种情况下,用户也许只希望使用selectedItem的值仅仅作为跟踪目的当一个新的数据集合下载完成以后。
构造computed observable
一个computed observable可以使用以下方式构造:
1.ko.computed( evaluator [, targetObject, options] )
- evaluator : 一个用来计算当前依赖监控属性的值的函数。
- targetObject : 可选,如果定义了,它将作为ko激活你的回调函数时候的this值。
- options : 可选,备用。
2.ko.computed(options),options包含以下属性:
- read : 必须的。用来计算当前依赖监控属性的值的函数。
- write : 可选的。使依赖监控属性writable,这个函数接收一个value参数以用来write到computed observable中。
- owner : 可选的。如果定义了,它将作为回调函数的this值。
- pure : 可选的。如果为true,这个computed observable将被设置为pureComputed observable。
- deferEvaluation : 可选的。不常用
- disposeWhen : 可选的。不常用
- disposeWhenNodeIsRemoved : 可选的。不常用。
computed observable的使用
- dispose() : 手动管理依赖监控属性,清楚所有依赖的订阅关系,这个函数非常有用,当你想停止computed observable的更新或者清除内存的时候
- extend(exteners) : 扩展方法。
- getDependenciesCount() : 返回当前computed observable的依赖数量。
- getSubScriptionsCount() :
- isActive() : 返回computed observable是否会更新在将来的某个时候,一个没有任何依赖的computed observable是不会被激活的
- peek() : 返回computed observable中没有创建依赖关系的值。
- subscribe(callback,[callbackTarget,event]) : 注册一个手动的订阅来接收computed observable改变的通知。
【Knockout】二、监控属性Observables的更多相关文章
- Knockout应用开发指南 第二章:监控属性(Observables)
原文:Knockout应用开发指南 第二章:监控属性(Observables) 关于Knockout的3个重要概念(Observables,DependentObservables,Observabl ...
- Knockout.Js官网学习(监控属性Observables)
前言 1.创建一个ViewModel <script type="text/javascript"> //1.创建一个ViewModel var myViewModel ...
- 2.Knockout.Js(监控属性Observables)
前言 1.创建一个ViewModel <script type="text/javascript"> //1.创建一个ViewModel var myViewModel ...
- (初)Knockout 监控属性(Observables)
1 创建带有监控属性的view model 1.1 Observables Knockout是在下面三个核心功能是建立起来的: 监控属性(Observables)和依赖跟踪(Dependency tr ...
- 第二章:监控属性(Observables)
关于Knockout的3个重要概念(Observables,DependentObservables,ObservableArray),本人无法准确表达它的准确含义,所以暂定翻译为(监控属性.依赖监控 ...
- KnockoutJS(2)-监控属性
本节主要涉及到3个内容: 1. 监控属性 Observables (这个用的比较多,但是其本身使用比较简单,唯一需要注意就是,它监控的对象是一个方法,所以取值和设置值的时候容易混淆) 2. 计算属性 ...
- Knockout 新版应用开发教程之创建view models与监控属性
最近抽出点时间研究MVVM,包括司徒正美的avalon,google的angular,以及Knockout,博客园Tom的Knockout指南 时隔2年了,ko更新了不少,所以文档也相应的变化了,所以 ...
- knockout的依赖属性dependentObservable和observable的监控的使用
1.Knockout是在下面三个核心功能是建立起来的:监控属性(Observables)和依赖跟踪(Dependency tracking) 声明式绑定(Declarative bindings) 模 ...
- Knockout开发中文API系列2–创建数据模型和监控属性
Observables,这个词的翻译来自汤姆大叔,对于部分翻译不是很准确的,欢迎大家留言,以得到更好的翻译. Knockout是建立在以下3个核心功能之上的: 1. 属性监控与依赖跟踪 2. ...
随机推荐
- CodeForces 548B Mike and Fun (模拟)
题意:给定一个n*m的矩阵,都是01矩阵,然后每次一个询问,改变一个格的值,然后问你最大有数是多少. 析:就是按他说的模拟,要预处理,只要把每行的最大值记下来,当改变时,再更新这一行的最大值. 代码如 ...
- HttpMessageConverter用法
HttpMessageConverter接口定义 * Strategy interface that specifies a converter that can convert from and t ...
- [置顶] 文件和目录(一)--unix环境高级编程
普通文件和目录linux中最多的两类文件,linux中一共有七种类型的文件,如下: 1.普通文件 2.目录 3.字符特殊设备 4.块特殊设备 5.FIFO,又叫命名管道 6.Socket,即套接字 7 ...
- 在VB中利用Nuget包使用SQLite数据库和Linq to SQLite
上午解决了在C#中利用Nuget包使用SQLite数据库和Linq to SQLite,但是最后生成的是C#的cs类文件,对于我这熟悉VB而对C#白痴的来说怎么能行呢? 于是下午接着研究,既然生成的是 ...
- 关于Linux vi命令 vi命令一览表
vi是所有UNIX系统都会提供的屏幕编辑器,它提供了一个视窗设备,通过它可以编辑文件.当然,对UNIX系统略有所知的人,或多或少都觉得vi超级难用,但vi是最基本的编辑器,学好了vi,以后在UNIX世 ...
- Swift学习笔记五
基础运算符 Swift的大部分运算符和C及OC相同,也分一元二元多元的,这里只记录一些Swift特有的性质或写法. 赋值运算符( = ) 在等号右边是一个有多个值的元组时,它的成员值可以分解并同时分别 ...
- JQuery Plugin 1 - Simple Plugin
1. How do you write a plugin in jQuery? You can extend the existing jQuery object by writing either ...
- 漫谈C#之关键字
每一种语言都有非常多的关键字,而且这些关键字也都大同小异,不过毕竟还是有些许的不一样.有些关键字大家碰到的多了,自然就熟悉了,但是有些关键字用得不大多,或者是新引入的,所以就不大熟悉了.我平常在用的时 ...
- DashClock
https://github.com/romannurik/dashclock/ https://github.com/nhaarman/DashPinkpop dashclock-master.zi ...
- Asp.Net MVC 3【Filters(过滤器)】
这里分享MVC里的Filters(过滤器),什么是MVC里的过滤器,他的作用是什么? 过滤器的请求处理管道中注入额外的逻辑.他们提供了一个简单而优雅的方式来实现横切关注点.这个术语是指所有对应用程序的 ...