View set controller

I’m trying to set different controller for specific view but this doesn’t work?

App.ContactsController = Ember.ObjectController.extend({
  test: '1',
});

App.ContactsEditController = Ember.ObjectController.extend({
  test: '2'
});

App.ContactsEditView = Ember.View.extend({
  controller: App.ContactsController,

  submit: function(evt) {
    console.log(this.get('controller').test) // 2
  }
})

I’m doing something wrong here?

Thanks for any help.

App.ContactsController is just the constructor. Use App.ContactsController.create({}) instead.

Actually I tried that also.

App.ContactsController = Ember.Controller.extend({
  actions: {
    create: function() {
      console.log('create')
    }
  }
});

App.ContactsNewView = Ember.View.extend({
  controller: App.ContactsController.create({}),
  submit: function(evt) {
    evt.preventDefault();
    this.get('controller').send('create')
    return false;
  }
})

Error:

Uncaught Error: Nothing handled the action ‘create’. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.

Actions from a view are sent to the controller of the template where the view is placed, not the controller that belongs to the view. And events go to the controller first, but then bubble through routes, not controllers. Try putting the create action in App.ContactsRoute.

I understand that,

I’m trying to say that

Set a custom controller to view is not working

The controller gives the view properties, it doesn’t handle events. Set the eventManager property if you want that. This is all stuff that is available in the API; I suggest reading it over.

http://emberjs.com/api/classes/Ember.View.html

I’m sorry but I’m talking about events, I’m talking about I want to different views to have one controller, so I don’t end up with many controllers.

You’re likely not going to get exactly what you want. This is a special use case and you’re going to have to repeat some code, that’s just the way it is. Place uniquely named events high in the chain so bubbled events always get caught, and use the controller needs functionality and computed aliases to get properties where you need them.

A few notes: 1.) If your views are simple and don’t require controller logic you don’t need to even define a controller.

2.) If there’s a specific controller that does have logic that you just need to re-use for a bunch of different views:

App.ReusableController = Ember.Controller.extend({
     foo : 'bar'
});

Then all you have to write later for a specific route is:

App.MyObjectController = App.ReusableController.extend({});

App.AnotherObjectController = App.ReusableController.extend({});

Also, let’s say you have a route structure like this

App.Router.map(function () {
    this.resource('comment', {path : '/comment'}, function () {
        this.route('add');
        this.route('edit');
        this.route('save');
    });
});

In this case when you are in the route comment.add you also in theory have three controllers dictating portions of your app: App.ApplicationController, App.CommentController and App.CommentAddController. You can access each controller above within a route using this.controllerFor() so if in all of your sub routes for comment you only need access to something specific on the App.CommentController controller you could use this to access it.

2 Likes