I ran into a problem in my Ember
application where setting multiple properties using Ember.set
and Ember.setProperties
produced a buggy result in the latter. Constructed an exact scenario here.
HBS:
Name: {{name}}<br>
Place: {{place}}<br><br>
<button {{action "modifyTogether"}}>this.setProperties({name:"Vignesh Raja",place:"Namakkal"})</button>
<br><br><br>
<button {{action "modifySeperately"}}>this.set("name","Vignesh Raja");<br>this.set("place","Namakkal");</button>
<br><br><br>
When set seperately, we get the latest value - {name:"Vignesh Raja", place:"Namakkal"}<br>
When set together, we get the latest value from the observer- {name:"Vignesh Raja", place:"Chennai"}<br>
<br>
<br>
JS:
import Ember from 'ember';
export default Ember.Controller.extend({
name:"Vignesh",
place:"Nmkl",
handleName1 : function(){
this.set("place","Chennai");
}.observes("name"),
actions:{
modifyTogether:function(){
this.setProperties({name:"Vignesh Raja",place:"Namakkal"})
},
modifySeperately:function(){
this.set("name","Vignesh Raja");
this.set("place","Namakkal");
}
}
});
In the above code, clicking first button (Ember.setProperties
) gives Name: Vignesh Raja Place: Chennai
, but clicking second (multiple Ember.set
) gives Name: Vignesh Raja Place: Namakkal
The problem I ran into was due to the
Ember Observer
assigned to thename
property.While updating separately, first
this.set("name","Vignesh Raja")
sets the value ofname
property. Then its observer is fired andplace
property gets changed toChennai
. After these, second statement,this.set("place","Namakkal")
is fired. So we getNamakkal
as the final value.Hence the result -
Name: Vignesh Raja Place: Namakkal
While updating together,
Ember.setProperties
buffers the observers until all the properties passed are updated. It groups the property changes usingEmber.beginPropertyChanges
, and the value changed notifications are not sent to the observers. Once the properties are set,Ember.endPropertyChanges
is called which in turn sends the notifications to the observers. So in the above example,this.setProperties({name:"Vignesh Raja",place:"Namakkal"})
, sets the propertiesname
andplace
and after finishing, the observer changes the propertyplace
toChennai
.Hence the result -
Name: Vignesh Raja Place: Chennai
.So if using the
Ember.setProperties
, Make sure any observer of any properties you set, won't change the value of other properties.