starshine wang
starshine wang

Reputation: 636

Ember.js 1.13: The right way to observe a passed-in attribute of component?

I'm trying to upgrade my project to Ember 1.13, and I'm a bit confused about the behavior of new attrs of component, especially when I have to observe them.

For example, my test component observes bar which is a parameter passed from outside. I know in Ember's new Glimmer engine, the component rerenders once any of its attribute changes. What I can't figure out is that the observer will also be fired at that time if I observe attrs.bar (I didn't modify bar!). But if I observe bar itself then it'll be fine.

The sample code:

HTMLBar:

 {{test-cpnt foo=foo bar=bar}}
 <input type="button" {{action 'tap'}} value="tap"/>

Controller:

 foo: 1,
 bar: 100,
 actions: {
   tap: function(){
     this.set('foo', this.get('foo')+1);
   }
 }

Component:

App.TestCpntComponent = Ember.Component.extend({
  barObv1: Ember.observer('bar', function(){
    console.log('bar observer is fired!');
  }),

  barObv2: Ember.observer('attrs.bar', function(){ 
    console.log('attrs.bar observer is fired!');
  }),
});

By tapping the button to change foo's value, we will trigger barObv2 as well. I've created a jsbin for demo: https://jsbin.com/qiwivu/2/edit?js,console,output

Does anyone know why the observer got triggered?

Upvotes: 4

Views: 780

Answers (1)

siva - abc
siva - abc

Reputation: 181

Well, you don't have to use observers since you are in Ember 1.13, you can make use of didUpdateAttrs which is triggered whenever an attribute is updated.

Ember.Component.extend({
....
 didUpdateAttrs({oldAttrs, newAttrs}) {
   let oldBar = get(oldAttrs, 'bar.value');
   let newBar = get(newAttrs, 'bar.value');

   if (oldBar !== new Bar) {
      // your logic here
   }
 }
....
});

If you intend to use observer, you can observe for the changes like below

barDidChange: Ember.observer('bar', function(){ 
 console.log('bar observer is fired!');
});

Listening for attrs.bar will not work properly, whenever an attribute is updated (including init), attrs are mutated every time which causes the observers to trigger, for more refer here. attrs are supposed to be used with angle-bracket components. Here is a nice article why we should not use attrs for curly components.

Upvotes: 1

Related Questions