Dependency Injection into ember views


#1

We have a view helper class that shows online or offline status. This is based on a singleton object that lets the view know if a given user is online or offline. Instead of creating a global singleton, I was hoping to use the DI container in Ember.

An example of how DI works in ember can be found here - Some Improvement ideas for our DI subsystem

// assume app-wide scope
App.inject(thingToInjectOn, property, thingToInject);
App.register(thingToInject, factory);

App.register('store:main', Store);
// example form ED. Injection on all contorllers
App.inject('controller', 'store', 'store:main');

// injection on a specific controller
App.inject('controller:person', 'facebook', 'service:facebook');

This works. I would like to do the same with views

App.register('app:presence', Presence);
App.inject('view', 'presence', 'app:presence');

While the container works great with injection of dependent objects for routes and controller, I was unable to inject a dependent object in the view. I would like some input on what is the right approach here and if it is ok to inject objects into views ?


#2

if the view is instantiate via the container the injection rules should apply. Can you provide an example?


#3

Well, the code was exactly this

App.inject('view', 'presence', 'app:presence');

I also tried

App.inject('main:view', 'presence', 'app:presence');
App.inject('application:view', 'presence', 'app:presence');

It would be great if there was a method to see all the registered keys for the factory from a given ember app.

We have moved the code into an ember data model and we tried doing the same but it did not work

App.User = DS.Model.extend(
  firstName: DS.attr('string')
  presence: (-> App.__container__.lookup 'pusher:presence' ).property()
  isOnline: (-> @get('presence').isOnline(@) ).property('presence.content.[]')

)

We tried injecting this way

 App.inject('model:user', 'presence', 'app:presence');

Thoughts ? I think it would be cool to have some guide/docs on how to cleanly use the container and if there is a better way to lookup an object from container instead of using __container__


#4

I had the same issue. I can not inject into views using the example code.


#5

I finally figured out where the keys for container are

the buildContainer method

 container.register('controller:basic', Ember.Controller, { instantiate: false });
    container.register('controller:object', Ember.ObjectController, { instantiate: false });
    container.register('controller:array', Ember.ArrayController, { instantiate: false });
    container.register('route:basic', Ember.Route, { instantiate: false });
    container.register('event_dispatcher:main', Ember.EventDispatcher);
    container.injection('router:main', 'namespace', 'application:main');
    container.injection('controller', 'target', 'router:main');
    container.injection('controller', 'namespace', 'application:main');
    container.injection('route', 'router', 'router:main');

As for views, they are defined in router#startRouting methods

 container.register('view:default', DefaultView);
 container.register('view:toplevel', Ember.View.extend());

#6

Did anyone find out how to “officially” inject into views? Injecting into “view” having no effect also causes trouble for Ember.SimpleAuth: https://github.com/simplabs/ember-simple-auth/issues/122


#7

I’d also like to know how should this be handled properly.

If I inject an object into all controllers, e.g.

application.inject('controller', 'session', 'session:main');

then, since templates/views read properties of controllers, why can’t I access the session property in a template like this?

<h2>User: {{session.userName}}</h2>

Instead, I have to do

<h2>User: {{controller.session.userName}}</h2>

Is this intended behavior?


#8

I am also unable to inject into views. What’s up with this?

UPDATE: I created an issue. https://github.com/emberjs/ember.js/issues/5323