官术网_书友最值得收藏!

  • Ember.js Cookbook
  • Erik Hanchett
  • 551字
  • 2021-07-16 12:58:02

Working with Ember observers in Ember.js

Observers are fundamental to the Ember object model. In the next recipe, we'll take our light example, add an observer, and see how it operates.

How to do it...

  1. To begin, we'll add a new observer called isOnChanged. This will only trigger when the isOn property changes:
    const Light = Ember.Object.extend({
      isOn: false,
      color: 'yellow',
      age: null,
      description: Ember.computed('isOn','color',function() {
        return 'The ' + this.get('color') + 'light is set to ' + this.get('isOn')
      }),
      fullDescription: Ember.computed ('description','age',function() {
        return this.get('description') + ' and the age is ' + this.get('age')
      }),
      desc: Ember.computed.alias('description'),
     isOnChanged: Ember.observer('isOn',function() {
     console.log('isOn value changed')
     })
    });
    
    const bulb = Light.create({age: 22});
    
    bulb.set('isOn',true); //console logs isOn value changed

    Ember.observer isOnChanged monitors the isOn property. If any changes occur to this property, isOnChanged is invoked.

    Note

    Computed properties versus observers

    At first glance, it might seem that observers are the same as computed properties. In fact, they are very different. Computed properties can use get and set methods and can be used in templates. Observers, on the other hand, just monitor property changes and cannot be used in templates or be accessed like properties. They don't return any values as well. With this said, be careful not to overuse observers. In many instances, a computed property is a more appropriate solution.

  2. Additionally, if needed, you can add multiple properties to the observer. Just use the following code:
    Light.reopen({  
    isAnythingChanged: Ember.observer('isOn','color',function() {
        console.log('isOn or color value changed')
      })
    });
    
    const bulb = Light.create({age: 22});
    bulb.set('isOn',true); // console logs isOn or color value changed
    bulb.set('color','blue'); // console logs isOn or color value changed

    The isAnything observer is invoked whenever the isOn or color properties change. The observer will fire twice as each property has changed.

Synchronous issues with the Light object and observers

It's very easy to get observers out of sync. If, for example, a property that it observes changes, it will be invoked as expected. After being invoked, it might manipulate a property that hasn't been updated yet. This can cause synchronization issues as everything happens at the same time.

  1. The following example shows this behavior:
      Light.reopen({
        checkIsOn: Ember.observer('isOn', function() {
          console.log(this.get('fullDescription'));
        })
      });
    
    const bulb = Light.create({age: 22});
    bulb.set('isOn', true);

    When isOn is changed it's not clear if fullDescription, a computed property, has been updated yet or not. As observers work synchronously, it's difficult to tell what has been fired and changed. This can lead to unexpected behavior.

  2. To counter this, it's best to use the Ember.run.once method. This method is a part of the Ember run loop, which is Ember's way of managing how code gets executed. Reopen the Light object and you will see the following:
    Light.reopen({
        checkIsOn: Ember.observer('isOn','color', function() {
          Ember.run.once(this,'checkChanged');
        }),
        checkChanged: Ember.observer('description',function() {
          console.log(this.get('description'));
        })
    });
    const bulb = Light.create({age: 22});
    bulb.set('isOn', true);
    bulb.set('color', 'blue'); 

    The checkIsOn observer calls the checkChanged observer using Ember.run.once. This method gets run only once per run loop. Normally, checkChanged would get fired twice; however, as it's being called using Ember.run.once, it outputs only once.

How it works...

Ember observers are mixins from the Ember.Observable class. They work by monitoring property changes. When any change occurs, they are triggered. Keep in mind that these are not the same as computed properties and cannot be used in templates or with getters or setters.

主站蜘蛛池模板: 那坡县| 山东省| 公安县| 陆河县| 永州市| 鹰潭市| 盈江县| 铁力市| 封开县| 杭锦旗| 孝义市| 汕头市| 怀来县| 贵德县| 安庆市| 乌苏市| 亚东县| 裕民县| 广水市| 台中市| 桂平市| 保定市| 尤溪县| 蒙自县| 扬中市| 华安县| 盐城市| 涞源县| 时尚| 台中县| 元江| 福贡县| 日土县| 林周县| 敦煌市| 漳平市| 盈江县| 梅河口市| 蒙阴县| 望江县| 石家庄市|