最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Ember.observer run on init - Stack Overflow

programmeradmin2浏览0评论

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 badges
Add a comment  | 

2 Answers 2

Reset to default 14

May 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

  1. Well, sometimes it might be necessary to fire the observer on initialization time.

  2. Ember.observer is an Ember namespace method, not part of Ember.Object's prototype. Therefore this.observer never exists, but addObserver() does.

  3. There is no need to invoke the handler, Ember runtime will invoke the handler when the property changes

  4. calling this._super is unnecessary unless it really does matter. In this case, if Person just extends Ember.Object calling super doesn't do anything.

    By default, does nothing unless it is overridden during class definition.

  5. 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.

  1. It unnecessarily places setting up the observer in the init hook.

  2. It sets up the observer inside the init hook incorrectly, using Ember.observer instead of this.observer, which won't even work.

  3. It fails to invoke (as opposed to setting up) the handler at init time.

  4. It fails to call init on the superclass.

  5. 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);
})
发布评论

评论列表(0)

  1. 暂无评论