in Ember.js I have route with model. Could you help me, when I'm on route playlist how to reload this route (or set new data to model) called by callback from another JS function? I've been looking to documentation so long, but no help for me.
App.PlaylistRoute = Ember.Route.extend({
setupController: function(controller, model) {
$.getJSON('api/playlist.php?' + Math.random().toString(36), function (data) {
controller.set('model', data);
});
}
});
Thanks a lot!
It seems the solution in the answer won't work for current route.
I had a same issue and tried the solution here and it worked.
http://discuss.emberjs.com/t/refresh-current-view-page-after-language-change/4291/5#post_5
In your route.
actions: {
sessionChanged: function() {
this.refresh();
}
}
and in your controller.
observeSession: function() {
this.send("sessionChanged");
}.observes("session.isAuthenticated"),
There are two ways of doing it.
One is write an action in playlist route and call this.refresh() inside it
For more information you can visit Ember Guide refresh method for route.
The other way is in your controller depending on the situation when you need to reload your route use
this.get('target.target.router').refresh();
any of the two would help you in refreshing your route.
A small note of refresh method below from ember guides:
Refresh the model on this route and any child routes, firing the beforeModel, model, and afterModel hooks in a similar fashion to how routes are entered when transitioning in from other route. The current route params (e.g. article_id) will be passed in to the respective model hooks, and if a different model is returned, setupController and associated route hooks will re-fire as well.
From a controller use transitionToRoute:
this.transitionToRoute('playlist', newModel);
From a route use transitionTo:
this.transitionTo('playlist', newModel);
For example, imagine you have an action on your controller
App.PlaylistController = Ember.ArrayController.extend({
actions: {
grabNewModel: function(){
//get some new model
this.transitionToRoute('playlist', newModel);
}
}
});
This answer appears first on google when searching how to refresh a route with the current accepted answer being out of date. If you really need to refresh a route and perform the model hook action again from an action in a controller then use the following:
In the route
#action
refreshModel() {
this.refresh();
}
In order to call this action in the controller use
this.send('refreshModel');
For example:
#action
performUpdate(event) {
event.preventDefault();
// Perform necessary action
this.send('refreshModel');
}
Note: This will send the action to the corresponding route for the controller it is called from, and update that route only and any child routes.
Related
Inside an application we allow users to create new records, related to an existing record. To achieve this, we use actions something like this:
createUser() {
var route = this;
var model = this.store.createRecord('user', {
client: route.modelFor('client'),
});
route.transitionTo('user.update', model);
},
The user.update route renders a user-form component, using the model that was passed in the transition. The same route is also used to update existing users.
The issue with this approach is as follows; when refreshing the page, the page errors because the route fails to find the respective record when querying the store (at this point, the URL is /users/null/update). Ideally I'd pass the client (or client.id) argument in the URL so that:
The page can be reloaded without issue.
The client associated with the user is set correctly.
How can I achieve this in Ember.js? I know that this can easily be done using nested routes (by nesting the user.update route inside a client route), but this doesn't make sense visually.
The relevant parts of the router are as follows:
this.route('clients');
this.route('client', {path: 'clients/:id'}, function() {
this.route('users');
});
this.route('user', {path: 'users/:id'}, function() {
this.route('update');
});
All I do in the user/update.hbs template is {{user-form user=model}}
The problem is that the model you just created has no id at that point because it is not saved, ember can´t route to a model without an id, if possible save the model before you try to transition to the route, if you don´t want to save the model because the user can cancel the action check this thread where a user had the same problem (if I understand you problem correctly), I provided a solution for that problem that I´m using in my own project
https://stackoverflow.com/a/33107273/2214998
I am accessing the query parameters in the route using the below code:
export default Ember.Route.extend({
afterModel: function(params, transition){
this.set('clientId', transition.queryParams.clientId);
},
setupController: function(controller) {
controller.set('clientId', this.get('clientId'));
}
});
The reason I am not using a controller is because I am feeding this data straight in to a component and I am of the understanding that in newer versions of Ember controllers will be phased out.
This is currently working however if I change any of the properties in the URL it doesn't update in the app unless I refresh the page or exit the route and re-enter it.
How can I "re-run" the route afterModel and update the properties which are passed to the component?
If the only option is to use a controller then I can implement this until a better solution comes along.
Try adding this to your route:
queryParams: {
'clientId' : {
refreshModel: true,
replace : true,
},
}
See here for more information.
I am trying to make a simple app using Ember.js. I am using yeoman ember.
I have following application template
<h1>Dashboard</h1>
<div class="content">{{outlet}}</div>
I have a few routes defined. Now what I am not being able to do is, find a way to update the text inside <h1> for different routes. For example,
if I navigate to /#/users I need it to change to Users.
if I navigate to /#/users/1 I need it to change to the model's firstname.
I tried this in ApplicationRoute
setupController: function(controller){
controller.set('title', 'Dashboard');
}
and changing to <h1>{{title}}</h1>
but it only works for ApplicationRoute and no other route!
setupController: function(controller){
controller.set('title', 'Users');
}
This does not work in UsersRoute. Even the output of the route disappears.
What is the right approach to get this to work!
How about you simply create an action in ApplicationRoute that sets the title as passed to it as an argument, and then have your sub route call that action in setupController. That should do the trick.
So in you application route:
//in application route
actions:{
updatePageTitle: function(title){
this.controllerFor('application').set('title', title);
}
}
And in your individual child route:
setupController:function(controller, model){
this.send('updatePageTitle', model.get('something'));
this._super(controller, model);
}
I'm working with the latest release of Ember JS (RC1), and I have an architectural problem :
I have a very simple use case : a list of users, and a form to add users.
My Router:
App.Router.map(function () {
this.resource('users', function () {
this.route('new');
});
});
My Routes:
App.UsersRoute = Em.Route.extend({
model:function () {
return App.User.findAll();
}
});
My Controller:
App.UsersNewController = Em.ObjectController.extend({
saveUser:function () {
//'content' contains the user
App.User.save(this.content);
// here i want to reload the list of users, but it doesn't work
// The application goes correctly to the url /users
// But doesn't call the 'model' function
this.transitionToRoute('users');
}
});
As I say in the above comment, when I create a new User, I'd like to redirect to the list of users (that part works) AND reload the user list by calling the 'model' method of the route (that part doesn't).
I could write a method in UsersController to reload the list, but then I would have duplication between UsersRoute and UsersController.
Can someone help me on this problem ?
Thanks
P.S. : here a fiddle http://jsfiddle.net/vsxXj/
Ember Documentation on the model hook:
"A hook you can implement to convert the URL into the model for this
route."
So i do not think that this hook is right for this case. I think you should use the setupController hook for this case. Try this:
App.UsersRoute = Em.Route.extend({
setupController(controller){
controller.set("content", App.User.findAll());
}
});
I have an action:
{{action create target="controller"}}
which I have targeted to the bound controller (rather than the router) like this:
App.AddBoardController = Ember.Controller.extend
create: ->
App.store.createRecord App.Board, {title: #get "boardName"}
App.store.commit()
//TODO: Redirect to route
How do I redirect back to a route from the controller action?
Use transitionToRoute('route') to redirect inside an Ember controller action:
App.AddBoardController = Ember.Controller.extend({
create: function(){
...
//TODO: Redirect to route
this.transitionToRoute('route_name');
}
...
In fact, this is not Ember idiomatic. From what I know, and what I have learnt from Tom Dale himself, here are some remarks about that code:
First, you should not transitionTo from elsewhere than inside the router: by doing so, you are exposing yourself to serious issues as you don't know in which state is the router, so to keep stuff running, you will quickly have to degrade your design, and by the way the overall quality of you code, and finally the stability of your app,
Second, the action content you are showing should be located inside the router to avoid undesired context execution. The router is indeed a way to enforce a coherent behavior for the whole app, with actions being processed only in certain states. While you are putting the actions implementation into Controllers, those actions can be called at anytime, any including wrong...
Finally, Ember's controllers are not aimed to contain behavior as they rather are value-added wrappers, holding mainly computed properties. If you nevertheless want to factorize primitives, maybe the model can be a good place, or a third party context, but certainly not the Controller.
You should definitely put the action inside the router, and transitionTo accordingly.
Hope this will help.
UPDATE
First example (close to your sample)
In the appropriated route:
saveAndReturnSomewhere: function (router, event) {
var store = router.get('store'),
boardName = event.context; // you pass the (data|data container) here. In the view: {{action saveAndReturnSomewhere context="..."}}
store.createRecord(App.Board, {
title: boardName
});
store.commit();
router.transitionTo('somewhere');
}
Refactored example
I would recommend having the following routes:
show: displays an existing item,
edit: proposes to input item's fields
Into the enclosing route, following event handlers:
createItem: create a new record and transitionTo edit route, e.g
editItem: transitionTo edit route
Into the edit route, following event handlers:
saveItem: which will commit store and transitionTo show route, e.g
EDIT: Keep reading, Mike's answer discusses some of the problems with this approach.
You can just call transitionTo directly on the router. If you are using defaults this looks like App.router.transitionTo('route', context).