2
votes

So my understanding from the Ember docs is that the pattern for views/controllers/models is as follows:

[view] <- [controller] <- [model]

(with views consuming controllers consuming models)

In my previous experience using Ember, I'd set up a view to consume a model, like so:

{{#with blogpost}}
    {{#view MyApp.BlogPostView contentBinding="this"}}
        <h1>{{title}}</h1>

        <p>{{content}}</p>
    {{/view}}
{{/with}}

Now say I create a controller:

MyApp.BlogPostController = Ember.BlogPostController.extend()

Where do I initialize this controller?

Looking at the Ember docs, it seems like this happens automatically if the controller is associated with a route, but what if I just want an ad-hoc controller which ties together a view and a model? This could be for an arbitrary component on my page.

Am I responsible for instanciating the controller? Should I use some kind of controllerBinding attribute? Will it be instantiated automatically with my model, or with my view?

Any advice appreciated; I'm comfortable with the model/view pattern in Ember, but I'm having some difficulty working out where controllers fit in.

1

1 Answers

3
votes

Looking at the Ember docs, it seems like this happens automatically if the controller is associated with a route

This is correct, a controller associated with a route will be automatically instantiated by ember when needed.

but what if I just want an ad-hoc controller which ties together a view and a model? This could be for an arbitrary component on my page. Am I responsible for instanciating the controller? Should I use some kind of controllerBinding attribute? Will it be instantiated automatically with my model, or with my view?

There are different way's to get your arbitrary controller instantiated automatically by ember without the needs of doing it yourself.

For the examples, let's assume you have a controller which is not associated with any routes called LonelyController,

App.LonelyController = Ember.ArrayController.extend({
  content: ['foo', 'bar', 'baz']
});

Approach 1

Let's assume you have a route and you hook into setupController, if you try here to request you LonelyController with this.controllerFor('lonely'); this will make ember instantiate it for you:

App.IndexRoute = Ember.Route.extend({
  setupController: function(controller, model) {
    this.controllerFor('lonely').get('content');
    // the above line will retrive successfully 
    // your `LonelyController`'s `content` property
  }
});

Approach 2

Another possible way to get your LonelyController automatically instantiated by ember would be by defining a dependence with the needs API in another controller:

App.IndexController = Ember.ObjectController.extend({
  needs: 'lonely',
  someAction: function() {
    this.get('controllers.lonely').get('content');
    // the above line will retrive successfully 
    // your `LonelyController`'s `content` property
  }
});

Using the needs API you could also doing something like this:

App.IndexController = Ember.ObjectController.extend({
  needs: 'lonely',
  lonelysContentBinding: 'controllers.lonely.content',
  someAction: function() {
    this.get('lonelysContent');
    // the above line will retrive successfully 
    // your `LonelyController`'s `content` property
  }
});

There are also some other combinations of the mentioned methods to get your LonelyController automatically instantiated, but I guess this should be more clear by now.

One last tip: to get a clue of what ember creates automatically under the hood you could also enable the generation logging to observe this in your console, which is very helpful, by doing:

var App = Ember.Application.create({
  LOG_ACTIVE_GENERATION: true
});

Hope it helps.