Ember学习(6):Observers
来源:互联网 发布:最流行编程语言 编辑:程序博客网 时间:2024/05/18 00:04
英文原址:http://emberjs.com/guides/object-model/observers/
Ember支持监听任何属性,包括计算型属性。你可以通过对函数使用observes来针对一个对象创建observer。
Person = Ember.Object.extend({ // these will be supplied by `create` firstName: null, lastName: null, fullName: function() { var firstName = this.get('firstName'); var lastName = this.get('lastName'); return firstName + ' ' + lastName; }.property('firstName', 'lastName'), fullNameChanged: function() { // deal with the change }.observes('fullName').on('init')});var person = Person.create({ firstName: 'Yehuda', lastName: 'Katz'});person.set('firstName', 'Brohuda'); // observer will fire因为fullName计算型属性依赖firstName属性,更新firstName也会触发fullName的observer。
观察者和异步
目前Ember中Observer都是同步的,这意味着observer方法会在他们观察的属性被改变的当时就被触发,因为这个原因,当属性不是同步方式使用时,容易引入一些bug。
Person.reopen({ lastNameChanged: function() { // The observer depends on lastName and so does fullName. Because observers // are synchronous, when this function is called the value of fullName is // not updated yet so this will log the old value of fullName console.log(this.get('fullName')); }.observes('lastName')});上面的observer依赖lastName,也需要调用fullName。因为observer是同步的,当这个函数被调用时,fullName的值还没有来得及更新,因此它会打印出fullName的旧值。
这种同步的机制也会导致同一个observer被触发多次,当这个observer同时监听多个属性时。
Person.reopen({ partOfNameChanged: function() { // Because both firstName and lastName were set, this observer will fire twice. }.observes('firstName', 'lastName')});person.set('firstName', 'John');person.set('lastName', 'Smith');
为了避免这样的问题,你应该使用Ember.run.once。这会保证任何你需要做的事情只会被执行一次,当所有绑定都是同步方式时,只在下一次run loop中发生一次。(这里还是有点不太理解,没有使用过,回头理解的更透彻了,再细说)
Person.reopen({ partOfNameChanged: function() { Ember.run.once(this, 'processFullName'); }.observes('firstName', 'lastName'), processFullName: function() { // This will only fire once if you set two properties at the same time, and // will also happen in the next run loop once all properties are synchronized console.log(this.get('fullName')); }});person.set('firstName', 'John');person.set('lastName', 'Smith');
观察者和对象初始化
只有一个对象的初始化完成了后,observer才会被触发。如果你需要observer在初始化发生时也被触发,你不能依赖set方法的副作用,你需要使用.on('init')来说明这个observer在初始化时也需要被触发。
App.Person = Ember.Object.extend({ init: function() { this.set('salutation', "Mr/Ms"); }, salutationDidChange: function() { // some side effect of salutation changing }.observes('salutation').on('init')});
没有被调用的计算型属性不会触发观察者
如果你从来没有对一个计算型属性使用get方法,它的observer永远也不会被触发,即使是该计算型属性依赖的属性发生了变化。你可以想象成它的值从一个unknown值变成另外一个。
这通常都不会影响应用的代码,因为计算型属性通常基本上被观察的同时也会被访问。举个例子,你访问了一个计算型属性的值,将它插入了HTML DOM(或者使用D3画出来),然后你监听它,当它改变时,你可以更新DOM。
如果你需要监听一个计算型属性,但是却不马上读取该计算型属性,你可以在init方法中读取它。
不使用Prototype扩展
如果你没有使用Ember的Prototype扩展,那么你可以使用Ember.observer方法来定义observer:
Person.reopen({ fullNameChanged: Ember.observer('fullName', function() { // deal with the change })});
在类定义外面使用
你也可以在一个类定义的外面通过使用addObserver方法来给某个对象添加observer:person.addObserver('fullName', function() { // deal with the change});
0 0
- Ember学习(6):Observers
- Ember学习(1):Ember核心概念
- Ember学习(7):Bindings
- Ember学习(2):Ember的命名约定
- Ember学习(3):类和实例
- Ember学习(4):计算型属性
- Ember.js学习总结
- Ember.js学习笔记
- Ember.js学习笔记
- Ember学习(8):REOPENING CLASSES AND INSTANCES
- URAL 1105 Observers Coloring (构造法)
- Ember
- Ember旅程系列(八) -- 使用Ember Data
- ZooKeeper Observers
- Ember学习(5):计算型属性和使用@each聚合数据
- Silicon Lab Ember zigbee学习杂谈----Tokens
- Ember.js 介绍系列 (待续)
- Ember.js 入门指南 (一)
- BeanUtils的使用
- 山东理工ACM[2444]正方形
- request.getSession(true)和request.getSession(false)的区别
- JavaIO流基础笔记(一)
- C语言交换两个数的值
- Ember学习(6):Observers
- POJ 2922 Honeymoon Hike(DFS/BFS+二分+枚举区间)
- OpenGL编程低级错误
- "无头单链表中删除节点"有感——变通 2014-03-18 17:56
- Java解析XML文档
- 用uboot 烧写uboot linux内核 文件系统到nandflash的 过程以及bootm go命令启动与区别
- hdu1251统计难题(字典树模版)
- Java 7之基础 - 强引用、弱引用、软引用、虚引用
- 关于集合视图UICollectionView