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

782 Views Asked by At

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?

1

There are 1 best solutions below

0
On

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.