2
votes

I know that EmberJS recommends using Routes to tie together models, views and controllers and this is a very convenient to setup the main content of a page. However suppose I have a sidebar that will show information from a second source. e.g an rss feed. Or a status panel attached to some server stats, I want a view that can be added to any template {{ view MessageView }} that connects to a separate model.

What is the 'ember way' to do this.

So far the best I can do is to have explicit View and Controller objects overriding the init function to wire them together. for example:

/*
 * The messages class is a free floating list of messages that can be plugged into any page. 
 * it is implemented as a view with a separate controller and model.
 * As its not associated with a route we need to bind the view, controller and model together directly using 
 * init statements.
 */

/**************************
* Model
**************************/

App.Message = DS.Model.extend({
    msg: DS.attr('string'),
    author: DS.attr('string'),
    date: DS.attr('date'),
    display_class: DS.attr('string')
});


/**************************
* Route
**************************/

//App.MessageRoute = Ember.Route.extend({
//  model : function() {
//      return this.get('store').findAll('message');
//      }
//});


/**************************
* Views
**************************/
App.MessageView = Em.View.extend({
      init: function() {
//          this._super();
            this.set("controller", App.MessageController.create());
          },

    });


/**************************
* Controllers
**************************/
App.MessageController = Em.ArrayController.extend({
      init: function() {
//          this._super();
            this.set("model", model : function() {
                return this.get('store').findAll('message');
            });
          },

});


/**************************
* Fixture
**************************/
App.Message.FIXTURES = [{
      id: 1,
      msg: "App website will be down for maintenance for 4 hours on Friday 29th Nov",
      author: { name: "Admin" },
      date: new Date('2013-11-18T19:00:00Z'),
      display_class: 'warning'
    }, {
      id: 2,
      msg: "Tropical Cyclone may affect North Island net week [read more](http://www.bom.gov.au/cyclone/)",
      author: { name: "WeatherMan" },
      date: new Date('2013-11-18'),
    }, 
    ];

However all I really need is some way to reproduce what the Route function already does.

Is there a better way?

Is there an example of a dashboard style page that has multiple independent view areas ?

Thanks Andrew

1

1 Answers

2
votes

The Ember way to tie together a model, controller & view without a route is {{render}} or {{control}}. (You can also use {{render}} with a route, if you override the route's renderTemplate hook to do nothing).

When you say {{render 'message'}}, Ember will instantiate MessageController and MessageView and connect them.

To connect to a model you have two choices: if the model can change, or there are multiple 'Message' views you can pass the model to render: {{render 'message' someMessage}}. Or, if you want to ensure only one message is displayed at a time and handle loading it in a route somewhere you can do:

this.controllerFor('message').set('model', someMessage);

in the setupController hook of a route that knows what someMessage should be. This could be the ApplicationRoute. You could also do this in an application initializer, but I think putting it in the ApplicationRoute is both more flexible and more explicit/maintainable.

Note that if the code to retrieve someMessage is a promise, you need to set it on the controller in the then of the promise.