I'm attempting to build an Ember app without prototype extensions and the Ember docs give examples of how to do this, but they don't include the example of when I want my observer to run on init. So currently if my code were written like this:
fullNameChanged: function() {
// deal with the change
}.observes('fullName').on('init')
The only example I can find to write it is like this:
Person.reopen({
fullNameChanged: Ember.observer('fullName', function() {
// deal with the change
})
});
So how would I tell this code to run on init?
I'm attempting to build an Ember app without prototype extensions and the Ember docs give examples of how to do this, but they don't include the example of when I want my observer to run on init. So currently if my code were written like this:
fullNameChanged: function() {
// deal with the change
}.observes('fullName').on('init')
The only example I can find to write it is like this:
Person.reopen({
fullNameChanged: Ember.observer('fullName', function() {
// deal with the change
})
});
So how would I tell this code to run on init?
Share Improve this question asked Apr 11, 2015 at 15:08 Taylor HobbsTaylor Hobbs 3133 silver badges13 bronze badges2 Answers
Reset to default 14May be you are looking for this
Person.reopen({
fullNameChanged: Ember.on('init', Ember.observer('fullName', function () {
// deal with the change
}))
});
OR (this won't fire handler if change happens on init
, use above on that case)
Person.reopen({
init: function(){
Ember.observer('fullName', function() {
// deal with the change
});
}
});
Alright, this edit for answer the mistakes(?) mentioned below
Well, sometimes it might be necessary to fire the observer on initialization time.
Ember.observer
is anEmber
namespace method, not part ofEmber.Object
's prototype. Thereforethis.observer
never exists, butaddObserver()
does.There is no need to invoke the handler, Ember runtime will invoke the handler when the property changes
calling
this._super
is unnecessary unless it really does matter. In this case, ifPerson
just extendsEmber.Object
calling super doesn't do anything.By default, does nothing unless it is overridden during class definition.
It's contextual, and as long as OP didn't specify anything about class definition it's beyond the scope of answering.
Nothing better explains than an example
The accepted answer actually contains five separate mistakes, of varying degrees of severity.
It unnecessarily places setting up the observer in the init hook.
It sets up the observer inside the
init
hook incorrectly, usingEmber.observer
instead ofthis.observer
, which won't even work.It fails to invoke (as opposed to setting up) the handler at init time.
It fails to call
init
on the superclass.It unnecessarily uses
reopen
.
1. No need to set up observer in init
hook
You do not need any procedural "call" or "invocation" in an init hook to set up an observer. Either of the two following forms will set them up automatically when the object is instantiated.
fullNameChanged: function() { } . observes('fullName')
observeFullNameChanged: Ember.observer('fullName', this.fullNameChanged.bind(this))
2. Use object.observer
for procedural setup of observers.
If you did want to set up the observer procedurally, then you call object.observer
, not Ember.observer
, which is defined for use as above. Calling Ember.observer
procedurally will accomplish nothing; Ember will have no idea of what object the property to observe lies. In this case, it would be this.observer('fullName', ...)
(although as mentioned above you actually don't need to do this at all; instead use the approach of point 1).
3. Invoke handler on init
But you also want to invoke the handler at init
time. There are three ways:
init: function() { this.fullNameChanged(); /* call super */ }
initFullNameChanged: Ember.on('init', this.fullNameChanged.bind(this))
fullNameChanged: function() { ... }.on('init')
where the third option uses the prototype extensions you don't want.
4. Calling super
from init
If you are going to have an init
hook, even though it's not needed, you need to call super
, or things will break down horribly:
init: function() {
...
this._super.apply(this, arguments);
}
5 No need for reopen
reopen
accomplishes nothing here. Just put the above properties into the class definition itself.
Solution
The correct answer to what is the equivalent of
fullNameChanged: function observer() { }.observes('fullName').on('init')
is therefore
fullNameChanged: function() { },
observeFullNameChanged: Ember.observer('fullName', this.fullNameChanged.bind(this)),
initFullNameChanged: Ember.on('init', this.fullNameChanged.bind(this))
It would be equivalent, and possibly more readable, to do this:
initFullNameChanged: Ember.on('init', function() {
// define and execute handler
(function fullNameChanged() { ... }());
// set up obsever
this.observe('fullName, fullNameChanged);
})