Observables(监控属性)
Knockout是在下面三个核心功能是建立起来的:

  • 1监控属性(Observables)和依赖跟踪(Dependency tracking)
  • 2声明式绑定(Declarative bindings)
  • 3模板(Templating)

这篇博客我将讲解第一个功能:监控属性和依赖属性。 在这之前, 我们来解释一下MVVM模式和view model的概念。

MVVM and View Models
Model-View-View Model (MVVM)是为了构建用户界面设计的。描述的是如何通过将一个复杂的页面分成3个部分,从而使界面简单化:

  • model: 你程序里存储的数据。这个数据包括对象和业务操作(例如:银行账户可以完成金钱交易), 并且独立于任何UI。当使用KO的时候,通常说是向服务器调用Ajax读写这个存储的模型数据。
  • view model: 一个对于UI的数据和操作的纯代码的描述。例如,如果你实现列表编辑,你的view model应该是一个包含列表项items的对象和暴露的add和remove列表项(item)的操作方法。

注意这不是UI本身:它不包含任何按钮的概念或者显示风格。他也不是持续数据模型,包含用户正在使用的未保存数据。
     使用KO的时候,你的view models是不包含任何HTML知识的纯JavaScript 对象。保持view model抽象可以保持简单,以便你能管理更复杂的行为。

  • view:一个可见的,交互式的,表示view model状态的UI。从view model展示信息,发送命令到view model(例如:当用户click按钮的时候),无论什么时候view model状态改变的时候更新。

使用KO的时候,你的view和你带有绑定信息的HTML文档类似,这些声明式的绑定管理到你的view model上。或者你可以使用模板从你的view model获取数据生成HTML。

创建一个view model,只需要声明任意的JavaScript object。例如:

你可以为view model创建一个声明式绑定的简单view。例如:下面的代码显示personName 值:

Activating Knockout
data-bind属性尽快好用但它不是HTML的原生属性(它严格遵从HTML5语法, 虽然HTML4验证器提示有不可识别的属性但依然可用)由于浏览器不识别它是什么意思,所以你需要激活Knockout 来让他生效。

激活Knockout,需要添加如下的 <script> 代码块

你可以将这个代码块放在HTML底部,或者放在jQuery的$函数或者ready 函数里,然后放在页面上面, 最终生成结果就是如下的HTML代码:

很多情况下你可能想知道ko.applyBindings使用的是什么样的参数
第一个参数是view model对象绑定的控件活动
第二个参数(可选),可以声明成使用data-bind的HTML元素或者容器。例如, ko.applyBindings(myViewModel, document.getElementById('someElementId'))。它现在是只有作为someElementId 的元素和子元素才能激活KO功能。 好处是你可以在同一个页面声明多个view model,用来区分区域。

Observables
现在已经知道如何创建一个简单的view model并且通过binding显示它的属性了。但是KO一个重要的功能是当你的view model改变的时候能自动更新你的界面。当你的view model部分改变的时候KO是如何知道的呢?答案是:你需要将你的model属性声明成observable的, 因为存在着一些特别的 JavaScript objects能够通知订阅者它的改变以及自动探测到相关的依赖。
例如:将上述例子的view model改成如下代码:

你根本不需要修改view – 所有的data-bind语法依然工作,不同的是他能监控到变化,当值改变时,view会自动更新。

Reading and writing observables
不是所有的浏览器都支持JavaScript的 getters 和 setters (比如IE),,所以为了兼容性,使用ko.observable监控的对象都是真实的function函数。

  • 读取observable当前的值,只需要直接调用监控属性(observable)(不需要参数),例如myViewModel.personName() 将返回'Bob', myViewModel.personAge() 将返回 123。
  • 写一个新值到监控属性(observable)上,调用这个observable属性并当新值作为参数。例如:调用 myViewModel.personName('Mary') 将更新name值为'Mary'。
  • 给一个model对象的多个属性写入新值,你可以使用链式语法。例如: myViewModel.personName('Mary').personAge(50) 将会将name更新为 'Mary' 并且 将age更新为 50.

监控属性(observables)的特征就是能够被监控(observed),例如其它代码可以说我需要得到对象变化的通知,所以KO内部有很多内置的绑定语法。所以如果你的代码写成data-bind="text: personName", text绑定注册到自身,一旦personName的值改变,它就能得到通知。(假设它是一个observable 的值)
当然调用myViewModel.personName('Mary')改变name的值,text绑定将自动更新这个新值到相应的DOM元素上。这就是如何将view model的改变传播到view上的。

Observables的显式订阅
通常情况下,你不用手工订阅,所以新手可以忽略这节。
对于高级用户,如果你要注册自己的订阅到监控属性(observables),你可以调用它的subscribe 函数。例如

KO的内部很多地方都会用到subscribe 函数。
大多数情况下,你不需要做这些,因为内置的绑定和模板系统已经帮我们处理好了。
subscribe 函数接受3个参数:callback是一个函数,无论何时通知发生的时候都会被调用;target (可选) 定义了再callback函数中this的值;event (可选; 默认: "change") 是接受事件通知event的名称

你也可以终止自己的订阅,如果你需要的话:首先得到你的订阅,然后调用这个对象的dispose函数,例如:

knockoutjs(二)的更多相关文章

  1. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(二)

    前言:上篇 JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(一) 介绍了下knockout.js的一些基础用法,由于篇幅的关系,所以只能分成两篇,望见谅!昨天就 ...

  2. KnockoutJs学习笔记(十二)

    value binding一般适用于input.select.textarea等form elements中,能够将view model中的属性和相关联的DOM element的值(value)连接起 ...

  3. Knockoutjs官网翻译系列(二) Observable 数组

    承接前文,前文书说道了KO框架中如何使用observable的视图模型属性来与UI元素进行绑定并自动进行双向更新的事儿.observable属性除了服务基础数据类型之外,还定义了专门为服务数组类型的o ...

  4. KnockoutJs学习笔记(二)

    这篇文章主要用于记录学习Working with observable arrays的测试和体会. Observable主要用于单一个体的修改订阅,当我们在处理一堆个体时,当UI需要重复显示一些样式相 ...

  5. knockoutjs如何动态加载外部的file作为component中的template数据源

    玩过knockoutjs的都知道,有一个强大的功能叫做component,而这个component有个牛逼的地方就是拥有自己的viewmodel和template, 比如下面这样: ko.compon ...

  6. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(一)

    前言:出于某种原因,需要学习下Knockout.js,这个组件很早前听说过,但一直没尝试使用,这两天学习了下,觉得它真心不错,双向绑定的机制简直太爽了.今天打算结合bootstrapTable和Kno ...

  7. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面

    前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码.博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一个什么工具直接生成页面效果,啥代码都不用写了,那该多爽.于是研究了下T4 ...

  8. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查

    前言:之前博主分享过knockoutJS和BootstrapTable的一些基础用法,都是写基础应用,根本谈不上封装,仅仅是避免了html控件的取值和赋值,远远没有将MVVM的精妙展现出来.最近项目打 ...

  9. knockoutJS学习笔记01:从拼接字符串到编写模板引擎

    开篇 关于knockout的文章,园里已经有很多大神写过了,而且都写得很好.其实knockout学习起来还是很容易的,看看官网的demo和园里的文章,练习练习就可以上手了(仅限使用,不包含研究源码). ...

随机推荐

  1. 常见的JAVA包

    java.lang 提供利用 Java 编程语言进行程序设计的基础类.最重要的类是 Object(它是类层次结构的根)和 Class(它的实例表示正在运行的应用程序中的类). java.util 包含 ...

  2. 如何消除MyEclipse导入jQuery库后出现的错误标记

    由于MyEclipse提供比较严谨的js校验功能,因此jQuery等前端框架导入到MyEclipse后均会提示错误,比较难看,如果要将校验去掉可以遵循下面步骤:1.点击菜单“MyEclipse”-&g ...

  3. Python开发【杂货铺】:模块logging

    logging模块 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式 ...

  4. telnet输入乱码的解决

    1.Win+R --- 运行窗口  输入cmd回车 2.输入telnet 主机 端口 3.连接主机发现无法输入 4.这里什么也不要输入,按下 ctrl+] 键 5.按下回车键,然后会弹出新的窗口,就可 ...

  5. npm总结

    1.npm install -g 模块               全局安装                 2.npm install 模块@version      安装具体摸个版本的模块     ...

  6. Vimium使用快捷键总结

    chrome 快捷键: ctrl+w 关闭当前标签  ctrl+t 新建标签 gg行首 shift+g 行尾 Vimium使用快捷键总结 j, <c-e> : Scroll down k, ...

  7. Android下安装应用不成功解决

    在手机上安装应用程序不成功,可以尝试把手机连接电脑,然后使用adb进行安装,adb安装命令: adb install Android_65632.apk 当出现: success!就表示成功,但当不成 ...

  8. SLP测试记录

    个人感觉来说这个游戏对我没有什么吸引力...完全不知道用户需求在哪...是我最不喜欢的一个游戏 不过听制作团队之前的介绍,这应该不算是一个游戏,而是一个游戏练习器?所以从游戏的角度来评判的话感觉有很多 ...

  9. python入门到精通[三]:基础学习(2)

    摘要:Python基础学习:列表.元组.字典.函数.序列化.正则.模块. 上一节学习了字符串.流程控制.文件及目录操作,这节介绍下列表.元组.字典.函数.序列化.正则.模块. 1.列表 python中 ...

  10. Media Queries使用方法

    1. 最大宽度max-width “max-width”是媒体特性中最常用的一个特性,其意思是指媒体类型小于或等于指定的宽度时,样式生效.如: @media screen and (max-width ...