Reputation: 538
I am wondering if there was a change in the way that Ember.Objects are created. Given the code below, I would not expect full_name to return "Joe Smith" as I am not using the ".get()" property accessor, but recently found that this worked and does return "Joe Smith". When is it safe to use simple dot notation and when should you use ".get('property')"?
note -this code works with ember 1.7
var Person = Ember.Object.extend({
first_name: '',
last_name: '',
full_name: function() {
return this.first_name + ' ' + this.last_name;
}.property()
});
var joe = Person.create({first_name: 'Joe', last_name: 'Smith'});
console.log(joe.get('full_name'));
Upvotes: 3
Views: 511
Reputation: 47367
Actually getting/setting the property right off of the object has worked since pre-ember. The place where it hurts you is when the property you are getting is a computed property or proxy property or you're setting and it's being observed (by anything, including dom).
Computed properties are stored in the meta of the object, and need to be evaluated in order to provide the value.
var Person = Ember.Object.extend({
first_name: '',
last_name: '',
full_name: function() {
return this.first_name + ' ' + this.last_name;
}.property('first_name', 'last_name')
});
var joe = Person.create({first_name: 'Joe', last_name: 'Smith'});
console.log(joe.full_name); // undefined
Example: http://emberjs.jsbin.com/kaxil/edit?html,css,js,console,output
This is really apparent in controllers and ember data. Calling get/set on an ObjectController
will attempt to get/set the property on the model instead of on itself mimicking a decorator pattern. Similarly with Ember Data where it proxies gets/sets down a chain of possible locations of the property (dirty, in transit, committed data).
var Person = Ember.Object.extend({
first_name: '',
last_name: '',
full_name: function() {
return this.first_name + ' ' + this.last_name;
}.property('first_name', 'last_name')
});
var joe = Person.create({first_name: 'Joe', last_name: 'Smith'});
var c = Ember.ObjectController.create({
model: joe
});
console.log(c.first_name); // undefined
console.log(c.get('first_name')); // Joe
Example: http://emberjs.jsbin.com/bebavi/edit?html,css,js,console,output
So, that being said, if you know a property exists right on the object and it isn't being proxied down to another object there is no harm in just using obj.property
for getting. Now if you are changing the property obj.property = 'foo';
then there is a lot more possible harm. Since Ember uses an observer pattern which is triggered through their use of .set(...)
you run the risk of changing a dependent property which won't notify dependent properties that it's changed.
var Person = Ember.Object.extend({
first_name: '',
last_name: '',
full_name: function() {
return this.first_name + ' ' + this.last_name;
}.property('first_name', 'last_name')
});
var joe = Person.create({first_name: 'Joe', last_name: 'Smith'});
console.log(joe.get('full_name'));
joe.first_name = 'foo';
console.log("should be foo smith:" + joe.get('full_name')); // should be foo Smith
joe.set('first_name','asdf');
console.log(joe.get('full_name'));
Example showing set not updating: http://emberjs.jsbin.com/cagufe/edit
You will generally be safer always using the getters/setters, though I'm admittedly lazy in the few situations where I know I don't need to use a getter.
Upvotes: 6