简体   繁体   中英

How to inject a computed property into every controller in Ember?

If I set some actions and a computed property in the application controller and want to use the computed property in another controller, I currently have to set this property in every other controller manually.

This is how I am doing it now:

App.ApplicationController = Ember.Controller.extend
  isOn: true
  actions:
    on: ->
      this.set('isOn', true);
    off: ->
      this.set('isOn', false);

App.IndexController = Ember.Controller.extend
  needs: ['application']
  isOn: Ember.computed.alias("controllers.application.isOn")

2 questions:

  • How can I inject this into every controller that is automatically generated?
  • Is this the best way to implement global actions/properties in Ember?

Theoretically you could use reopenClass to reopen Ember.Controller and extend it to do what you need. I just tried it in a jsfiddle and I couldn't get that to work.

What I did get to work was Ember.Mixin .

App.IsOn = Ember.Mixin.create({
  needs: ['application'],
  isOn: Ember.computed.alias("controllers.application.isOn")
})

App.IndexController = Ember.Controller.extend(App.IsOn,{});

It doesn't handle automatically generated controllers, but it does let you put the functionality into controller with just one line if you don't need the controller for anything else.

Here's a jsfiddle with everything working:

http://jsfiddle.net/DqeLv/

EDIT: I should also add that you want to have the toggleOn method in your ApplicationRoute instead of ApplicationController . Bubbling of events goes from the most specific controller, then to the route for that controller, then up to each successive parent route (but not controller).

So, say you're at "/users/new" and trigger an action, it will go to :

UsersNewController => UsersNewRoute => UsersRoute => ApplicationRoute

EDIT #2: OK, after getting some sleep I was able to get reopen to work so that auto generated controllers get the isOn property atuomatically.

Ember.Controller.reopen({
    needs: ['application'],
    isOn: Ember.computed.alias("controllers.application.isOn")
});

It seems that this only works for "generic" controllers, not for instances of ArrayController or ObjectController (only for routes that don't return a model ).

If you want it to work for auto generated ArrayController and ObjectController instances you can reopen those two classes.

Ember.ArrayController.reopen({ ... })

http://jsfiddle.net/HTPaF/2/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM