App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
// `controller` is the instance of ApplicationController
controller.set('title', "Hello world!");
}
});
App.ApplicationController = Ember.Controller.extend({
appName: 'My First Example'
});
This is basic - but I want to understand.
I understand that ember creates objects in memory - so I would expect App.ApplicationController to be created when the application is booted/created. And then
controller.set('title', "Hello world!");
would set a property on that controller called title to the value 'Hello world!".
What I donât understand is that the next line
App.ApplicationController = Ember.Controller.extend({
appName: 'My First Example'
});
seems to create the App.ApplicationController (and set the property appName.
Is it the case that ember runs all object creation first?
Is the App.ApplicationController object âalwaysâ created on application start up? Would it show in the Chrome Ember inspector extension?
Why was this code not
App.ApplicationController.set('appName', "My First Example");
or
App.ApplicationController.appName = "My First Example";
When Ember.Thing.extend({}) is called, this is basically a constructor. .set isnât required because the object is not yet instantiated. Later when the application is actually being âbootedâ these various objects are create (or left to be lazy created when needed).
You are not creating it again here but defining the classes functionality. You âextendâ from Ember.Controller because you want it to act as a controller class. When Ember looks for an instance of ApplicationController then it will use your App.ApplicationController class to create it.
If you havenât defined your own App.ApplicationController then Ember will create an instance of Ember.Controller (or Object/ArrayController) for you automatically - this cuts down the amount of boilerplate code you need to write but it does increase the apparent âmagicâ when learning.
You donât have to call it. Ember does it automatically. If you donât define extend it, it will be created anyway, just without any overridden properties.
The ApplicationController becomes a property in the registry and is insantiated for you by calling create on the constructor.
Say we have an app with nothing in it apart from the js script src files and
var App = Ember.Application.create();
According to Ember inspector under routes the ApplicationRoute is created and assigned a generated ApplicationController controller and ApplicationRoute and this route contains a single index route with URL of #/
Routes are higher up the hierarchy than Controllers. The âMy First Exampleâ get overwritten with âHello worldâ after itâs instantiated. So appName is âMy First Exampleâ, but for a very short period of time, before being set to âHello world!â
Youâre asking the wrong question. Itâs not really a matter of hierarchy. Itâs just that route holds a singleton controller instance for the entire app lifespan, and offers you a way to make changes to it so that the controller can be updated as the user navigates different pages. Here is a code complete example:
App.Router.map(function() {
this.resource('users', { path: '/users/:username' });
});
App.UserRoute = Ember.Route.extend({
model: function(urlParams) {
return urlParams;
},
setupController: function(controller, model) {
controller.get('name') == "instance default name"; //only the first time this is called!
//called once each time the route is entered or the route's model changes
controller.set('name', model.username);
controller.constructor.prototype.name == "class default name";
}
});
App.UserController = Ember.Object.extend({
init: function() {
this.set('name', "instance default name");
},
name: "class default name"
});
With this example you will get the desirable, standard behavior: a single backing object for your templates that will have itâs propert[y/ies] updated as the user navigates around.
The distinction between class and instance properties is more a normal OO javascript difference. In plain OO javascript class values, stored on the prototype, are never deleted but only masked by instance values. You might delete an instance property using the delete keyword, and you would see the prototypeâs definition instead. With emberâs get/set there is no delete operation, so the distinction bears no relevance unless youâre considering performance. âclass default nameâ will appear in memory only once, whereas âinstance default nameâ would end up in memory many times if you, created many instances of UserController.