Relationship of access model from view

I have custom and working models with toIt / hasMany relation:

App.User = DS.Model.extend({ name: DS.attr('string'), workspace: DS.belongsTo('App.Workspace') }); App.Workspace = DS.Model.extend({ name: DS.attr('string'), users: DS.hasMany('App.User') }); 

I have a controller setup and a view when the controller model property is set to a valid user.

 App.ApplicationRoute = Ember.Route.extend({ setupController: function() { this.controllerFor('test').set('model', App.User.find(1)); } }); 

The following code and output shows that the belongsTo association was not loaded at runtime. What is the correct way to access a workspace (through a user) from a view class?

 App.TestView = Ember.View.extend({ didInsertElement: function() { var self = this; console.log('first try: '); console.log(this.get('controller.model.workspace')); setTimeout(function() { console.log('second try: '); console.log(self.get('controller.model.workspace')); }, 1000); } }); 

Outputs;

 // first try: // null // second try: // Class { ... } 

I can access the workspace in the template via {{model.workspace}} - how can I do the same in the view class?

+4
source share
1 answer

What is the correct way to access a workspace (through a user) from a view class?

Your method this.get('controller.model.workspace') is the right way to access the workspace from your view. But, as your example shows, the didInsertElement () hook is the wrong place for this. Since App.User.find(1) is asynchronous, you cannot count on model.workspace (or even model ), which is available when rendering a template. This is why your console.log returns null for the first time.

This may not be obvious, since Ember works very hard to eliminate explicit forms of asynchronous behavior. Since it immediately returns a reference to the model, we can expect that App.User.find() will be synchronous, but it is not. See managing-asynchrony for more details.

I can access the workspace in the template via {{model.workspace}} - how can I do the same in the view class?

Behind the scenes, handlebars binds {{model.workspace}} to your model and redraws the template when the value changes. You should use a similar method from your view class. Depending on what you want to perform, you can use a binding, a computed property, or an observer. For instance:

 App.TestView = Ember.View.extend({ workspaceChanged: function() { console.log('workspaceChanged to: '); console.log(this.get('controller.model.workspace')); }.observes('controller.model.workspace') }); 

Also see Bindings. Observers, Computable Properties: What should I use when?

+10
source

All Articles