Ember update parent route's model after save record - ember.js

I'm working on an Ember application with the intent of learning. I've setted on a UI where a parent route and template when first opened features a table of, for example, today’s items in the left hand column, and an area to the right that varies: details about an item, form for new/edit item, search, etc.
The trouble I have run into is that when I save a new item, the left hand table from the parent route is not updated with the new item. Having trouble finding a way of getting that route to refresh. The closet I came was by using pushObject on the model.
things template:
{{partial "things/table"}}
{{outlet}}
router.coffee
#resource "items", ->
#route "item", {path: "/:item_id"}
#route "new", {path: "/new"}
items route:
ItemsRoute = Ember.Route.extend(
model: -> #store.find 'item'
)
items new route:
ItemsNewRoute = Ember.Route.extend
renderTemplate: ->
this.render('items/form')
model: ->
#store.createRecord('item')
setupController: (controller, model)->
controller.set('model', model)
items new controller:
ItemsNewController = Ember.ObjectController.extend(
needs: 'items'
actions:
submit: -> #model.save().then(console.log('saved'(, console.log('failed'))
cancel: -> #transitionTo('items')
transitionAfterSave: (->
if #get('content.id')
#transitionToRoute('items.item', #get('content'))
).observes('content.id')

submit: -> #model.save().then(this.didSave.bind(this), console.log('failed'));
didSave: function() {
console.log('saved');
var route = this.container.lookup("route:items.index"); // use the name of route you want to refresh
route.refresh();
}

Related

Using ember.js, why is my sorting not working?

I have a model called discussions that I'm trying to sort by ID. I'm trying to display this sorted list of discussions in two places in my app, first at /discussions where the list sorts as I would expect, and then as a module on another page, /syndicates/0/activity, where the list sorting does not work.
I'm defining the sort in my DiscussionsController
App.DiscussionsController = Ember.ArrayController.extend
sortProperties: ['id'],
sortAscending: true
isThisControllerBeingCalled: true
which should be called by default at '/discussions'. Here's the route:
App.DiscussionsRoute = Em.Route.extend
model: ->
#store.find 'discussion'
renderTemplate: ->
#render 'discussions',
into: 'application',
outlet: 'full'
for the discussions module at '/syndicates/0/activity' I'm pulling in the discussions via setupController with a controllerFor:
App.SyndicatesRoute = Em.Route.extend(
controllerName: 'discussions'
model: ->
#store.find 'syndicate'
renderTemplate: ->
#render 'syndicates',
into: 'application',
outlet: 'syndicates'
#render 'discussion_module',
into: 'application',
outlet: 'left',
controller: 'discussions'
setupController: (controller, model) ->
#controllerFor('discussions').set('discussions_for_module', #store.find 'discussion')
)
For /syndicates/0/activity the discussions remain unsorted. I tried to confirm that the discussions controller was being called successfully by setting a property in the controller, which I could see in both places.
Any idea why the discussions are not being sorted?

Using transitionToRoute with a model with a custom slug

I've got an ember-data model that has an id as well as a server-generated custom slug attribute (which is prefixed with the id if that matters).
I'd like to use the slug instead of the id in all public routres. For that purpose, I have changed the router:
App.Router.map ->
#resource 'strategies', path: '/strategies', ->
#resource 'strategy', path: ':strategy_slug'
and overwrote the serialize method of the respective route:
App.StrategyRoute = Ember.Route.extend()
serialize: (model) ->
{
strategy_slug: model.get('slug')
}
Unfortunately, this does not seem to work when using transitionToRoute from a controller to transition to, e.g., /strategies/123-test:
App.ExampleController = Ember.ObjectController.extend()
[...]
actions:
showDetails: ->
#transitionToRoute("/strategies/#{#get('slug')}")
false
(where #get('slug') returns '123-test')
All output I get in the console after invoking the showDetails action is:
Transitioned into 'strategies.index'
Ember does seem to recognize the slug-based route.
Ember: 1.5.0-beta.2+pre.3ce8f9ac
Ember Data: 1.0.0-beta.6
Is there anything I may have missed?
Edit:
The following variant works and is feasible in this case, but I have another use-case where I have only access to the URL.
App.ExampleController = Ember.ObjectController.extend()
[...]
actions:
showDetails: ->
#transitionToRoute('strategy', #get('content'))
false
I eventually figured out how to solve this. The key is to add a model method to the router, which knows how to turn a slug into a model:
App.StrategyRoute = Ember.Route.extend()
model: (params, transition) ->
App.store.getById('strategy', parseInt(params.strategy_slug))
serialize: (model) ->
{
strategy_slug: model.get('slug')
}

modelFor parent route stopped working as before

Given the following routes:
App.Router.map ->
#resource 'locations', path: '/:location_id', ->
#route 'events', path: '/events/:date'
App.LocationsEventsRoute = Ember.Route.extend
model: (params) ->
location_id = #modelFor('locations').get('id')
console.log location_id
Accessing "/#/gothenburg-se/events/2013-09-03", location_id returns null. This worked before v1.0. What changed and how do I fix this?
This is likely due to changes in Ember Data for 1.0.beta.1. You might want to check out the transition document.
https://github.com/emberjs/data/blob/master/TRANSITION.md
I think something like this would work for your route:
App.LocationsEventsRoute = Ember.Route.extend({
model : function(params){
// find returns a promise
var locProm = this.store.find('location',params.location_id);
// once the promise has resolved you can log the id
locProm.then(function(loc){
console.log( loc.get('id') );
});
// return the promise immediately and let Ember resolve it
return locProm;
}
});

Ember dynamic segment is empty

Please see http://jsfiddle.net/kt2Hz/
I have read the docs, api and browsed the source code of Ember. No luck!
The routes:
App.Router.map ->
#resource 'customers', path: 'my_customers', ->
#resource 'customer', path: '/:customer_id', ->
#route 'edit', path: '/my_edit'
App.CustomerEditRoute = Ember.Route.extend
setupController: (controller, model) ->
controller.set('content', model)
alert("inspect: #{Ember.inspect(model)}")
The alert output is "inspect: undefined"
And if I check the params, the object is empty:
App.CustomerEditRoute = Ember.Route.extend
model: (params) ->
alert("inspect: #{Ember.inspect(params)}")
The alert output is "inspect: {}"
the dynamic segment is only passed to the customer route, not the nested ones. so if you change the model hook in your CustomerEditRoute to
model: (params) ->
return this.modelFor("customer")
it should work.
(pretty much the same problem as here btw.)

ember.js controller properties

i'm trying to set a property of a controller
Trying to do so
{{view Ember.Select contentBinding="App.tastingsController.names"}}
it does not work
App.tastingsController = Ember.ArrayController.extend
names: ["Velato", "Abbastanza limpido", "Limpido", "Cristallino", "Brillante"]
while this version is working correctly (but gives this warning:WARNING: The immediate parent route did not render into the main outlet and the default 'into' option may not be expected )
App.tastingsController.names = ["Velato", "Abbastanza limpido", "Limpido", "Cristallino", "Brillante"]
here's my routes:
App.Router.map ->
#route "home", { path: "/" }
#route "about"
#resource "tastings", ->
#route "new"
#resource "tasting", { path: ":tasting_id"}
Can you explain me why?
( found it here)
thank you
Marco
There are a few issues with your code:
App.tastingsController should be named App.TastingsController. Controller Classes should begin with a capital letter.
You are getting a warning because you skipped a template within the route hierarchy. I need more information on the routes to help fix this.
If you need to set a property on the controller (such as names in your case), there are two ways to do it:
Either set it in the route:
App.TastingsRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('names', names: ['list', 'of', 'names']);
}
});
Or you can set it directly when defining the controller class:
App.TastingsController = Ember.ArrayController.extend({
content: [],
names: ['list', 'of', 'names']
});
When you need to reference a controller from the view/template, don't name the entire controller class. Just use the property you want to bind to (assuming your view's controller is App.TastingsController)
{{view Ember.Select contentBinding="names"}}
Hope this helps.