How to create controller with own model without route in Ember.js? - ember.js

I have App.HomeRoute, which doesn't has model, but elements on this page must have their own models.
I use render helper for render these elements, but how I must to load models for they?

I'm not sure the design is correct, but you can "load" other models using setupController method in your route.
App.YourRoute = Ember.Route.extend({
setupController: function(controller, model) {
this._super(controller, model);
// set other properties
var a = this.store.find("modelA");
controller.set("a", modelA);
var b = this.store.find("modelB");
controller.set("b", modelA);
}
});
Now in your template just use them
{{each a}}
<div>{{id}}</div>
etc...
{{/each}}

Related

What is the correct way to access the model from a controller in Ember

I was wondering what the correct way to access the model from the controller?
I noticed that in the init of the controller the model is still null
#controller.js
init(){
console.log(this.model); // IS NULL
}
But the setupController method has the populated model. Therefore currently I am calling a controller's method from the setupController and an passing the model over there. Is this fine?
I was thinking there would be a callback method in the controller which would automatically be called when the controller is setup.
route.js
model() {
return this.store.findAll("post");
},
setupController(controller, model){
controller.set('model', model);
}
This will give console log model which is collection of post object.
controller.js
init(){
console.log(this.model);
}
We do this most of the times especially if you use RSVP promise
you chose what will be the model on your controller.
Example
model(params) {
return Ember.RSVP.hash({
lecture: this.store.findRecord('section', params.section_id).then((section)=>{
return this.store.createRecord('lecture',{
section: section
});
}),
section:this.store.findRecord('section', params.section_id),
course: this.store.query('course',{filter:{section_id:params.section_id}})
});
},
setupController(controller,model){
controller.set('model', model.lecture);
controller.set('section', model.section);
controller.set('course', model.course);
}
Note if you only have just simple model on route
model(params) {
return this.store.findRecord('course', params.course_id);
}
and you don`t have to do any setup on controller which is possible this will also give you model on controller.
setupController hook method will set model as property to controller.
setupController(controller,model){
this._super(...arguments);
}
You can get model just like normal other properties in controller. this.get('model')

How to set/modify model in controller

I'm doing a basic example for ajax operation in ember 1.7.0, What I did is have a model in route and did a ajax get for raw data.
App.IndexRoute=Em.Route.extend({
model:function(){
return Em.$.get('data.json');
},
}
Now in controller I want to modify this for the template, I tried
App.IndexController = Ember.Controller.extend({
init:function(){this._super();
var newmodel=this.get('content');
....some modification...
this.set('model',newmodel);
}
}
but this is not working.
So how basically One modify the model? This should be in setupController or in controller?
if need be how to get and set model in controller? Another confusion is on when to create and when to extend the controller and route?
Thanks.
Go for setupController hook in your route
App.IndexRoute = Em.Route.extend({
model: function() {
return Em.$.get('data.json');
},
setupController: function(controller, model) {
this._super(controller, model);
//Some modifications
//..
//end of modificaitons
controller.set('model', model);
}
});
extend() is used to create subclass for any class, for instance, Ember.ArrayController. If you want to overwrite the properties (methods) of the existing class you can go with extend.
create() is used to create new instance of a class. Refer this http://emberjs.com/guides/object-model/classes-and-instances/
No need to use setupController hook of Route until you want to set any properties for the controller.
If your Route have model hook and return data, then you can access model directly in your controller by using
var model = this.get('model');
At the same time you can use setters to update/modify model.
this.set('model',newdata);
Have a look at simple bin http://jsbin.com/fesux/edit
Kindly have a look at Ember.set and Ember.get also
You can utilize a setupController to handle this
App.IndexRoute=Em.Route.extend({
model:function(){
return Em.$.get('data.json');
},
setupController: function(controller, model){
controller.set('model',model);
}
}
The setupController hook receives the route handler's associated controller as its first argument. In this case, the IndexRoute's setupController receives the application's instance of App.IndexController.
The default setupController hook sets the model property of the associated controller to the route handler's model.
If you want to configure a controller other than the controller associated with the route handler, use the controllerFor method.
More details here:
http://emberjs.com/guides/routing/setting-up-a-controller/

ember.js one controller/view for more models

I have several (simple) models like languages, departments etc. They only contains name and id properties (columns). I want to make a controller and view, which controls the CRUD functions. How should i approach this problem to have one controller for several models?
Is it possible to load models from a routing variable?
pseudo code
somecontroller/modelname
App.IndexRoute = Ember.Route.extend({
model: function(modelname) {
return this.get('store').find(modelname);
}
});
You can load multiple models from the model hook and assign them to controller properties. e.g.
App.IndexRoute = Ember.Route.extend({
model: function(modelname) {
var store = this.get('store');
return Ember.RSVP.hash({
foos: store.find('foos'),
bars: store.find('bars')
});
},
setupController: function(controller, model) {
controller.set('foos', model.foos);
controller.set('bars', model.bars);
}
});
Ember.RSVP.hash will return a promise that waits on the promise values of all properties of the passed object, and will then fulfill with an object with the same property names and the promise fulfillment results as values.
By overriding setupController, you can determine what properties are set on the controller and with what values.
Here is two ways that you can do it to get two models on a route
/*
* Use the model hook to return model, then
* setController to set another model
*/
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('languages');
},
setupController: function(controller, model) {
this._super(controller, model);
controller.set('department', this.store.findAll('department'));
}
});
/*
* Can return a Hash of promises from the model hook
* and then use those as your models
*/
App.RsvphashRoute = Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
langs: this.store.find('languages1'),
dept: this.store.find('department1')
});
}
});
Here is jsbin of them in action. Hope it helps:
http://emberjs.jsbin.com/basoneno/1/edit

Nested routes loads the parent model

I have a nested route structure like this:
App.Router.map(function() {
this.resource('user', {path: '/user/:user_id'}, function() {
this.route('followers', {path: '/followers'});
});
});
when I hit the user/123/followers route I would expect that it automatically fetch the model from user/123/followers, but it just fetches the user model from user/123 again. What do I need to add so it fetches the right data for the route?
Each route have your own model, and this isn't propaged, by default.
So App.UserRoute model, returns the current model like expected:
App.User.find(params.user_id)
But because App.UserFollowersRoute have your own model hook, then you have to provided it.
You can do this easily using the modelFor.
App.UserFollowersRoute = Ember.Route.extend({
model: function() {
return this.modelFor('user');
}
});
The modelFor look for a model from a named route. So modelFor('user'), will retrieve the model from App.UserRoute.
And in your user/followers template, you will have the current user, in the current context:
<script type="text/x-handlebars" data-template-name="user/followers">
<h2>{{name}} followers:</h2>
<ul>
{{#each followers}}
<li>{{name}}</li>
{{/each}}
</ul>
</script>
Here a sample with this working
Ember will automatically call User.find(123) when you hit /user/123/... because that is the default model hook for App.UserRoute. If you want to fetch additional data when the followers route is accessed, define a model hook for App.UserFollowersRoute:
App.UserFollowersRoute = Ember.Route.extend({
model: function() {
user = this.controllerFor('user');
// Now find and return the list of followers
}
});

Specify controller and model on a view that doesn't have a router

I have a simple app that is using ember-data to load from a RESTful web service and display the data using the route to specify the model.
App.AreasRoute = Ember.Route.extend({
model: function() {
return App.Area.find();
}
});
Then I can render the data in the handlebars template using {{#each content}}
But I want to have a second area of data from a different model displayed on the page as well. I started by creating a View and then rendering the view as part of my application template using {{view App.AnotherView}} which correctly renders the view.
However, this view doesn't have a route and therefore I have nowhere to tell it where to get it's data from. How do I do this?
The best place to load additional content is in the setupController hook of the route.
For example, if you define your route as
App.AreasRoute = Ember.Route.extend({
model: function() {
return App.Area.find();
},
setupController: function(controller) {
controller.set('someArea', App.Area.find('area_id'));
}
});
Then the Area model with id area_id can be accessed by {{someArea}} in your template.