The layout of my UI is a list (outlet "sub-navigation") / detail (outlet "outlet") as described in one of my previous questions.
The details sometimes contains a read-only version of the model and sometimes there's a "edit" data version rendered in the main outlet.
One of my router's resources is a nested one:
App.Router.map(function () {
// ...
this.resource('offers', function () {
this.resource('offer', { path: '/:offer_id' }, function() {
this.route('edit');
});
});
// ...
});
Before I list the source code of my routes, let me explain my problem.
All works fine: I can open open the page with no offer, just the list. I view an offer and the offer is shown. I click on "edit offer" and I can edit and save the changes. After saving, in my controller I redirect (back) to the offer (read-only) page:
// in the save function:
var offer = this.get("content");
// ...
offer.on('didUpdate', function () {
controller.transitionToRoute("offer", offer);
});
// ...
store.commit();
But the next page, which should be the offer detail, is empty. The page-title section still contains the template from the edit route and the main outlet is empty.
How can I let Ember re-render the OfferRoute template?
Here my routes which contain the various renderTemplate calls:
App.OffersIndexRoute = Ember.Route.extend({
renderTemplate: function () {
this.render('offer-list-title', { into: 'application', outlet: 'page-title' });
this.render('offer-list-content', { into: 'application' });
}
});
App.OffersRoute = Ember.Route.extend({
model: function () {
return App.Offer.find();
},
renderTemplate: function () {
this.render('offer-list', { into: 'application', outlet: 'sub-navigation' });
}
});
App.OfferRoute = Ember.Route.extend({
setupController: function (controller, model) {
controller.set('content', model);
controller.set('offerTemplates', App.OfferTemplate.find());
controller.set('contentBlockTemplates', App.ContentBlockTemplate.find());
},
model: function (params) {
return App.Offer.find(params.offer_id);
},
renderTemplate: function () {
this.render('offer-title', { into: 'application', outlet: 'page-title' });
this.render('offer-content', { into: 'application' });
}
});
App.OfferEditRoute = Ember.Route.extend({
renderTemplate: function () {
this.render('offer-edit-title', { into: 'application', outlet: 'page-title', controller: 'offer' });
this.render('offer-edit', { into: 'application', controller: 'offer' });
}
})
UPDATE (solution)
With the help of the two answers below and a lo of try/error and debugging I got it working. I basically added an OfferIndexRoute
, but I also had to define the model
using this.modelFor("offer")
.
I don't know if this is the most elegant solution, but it works. So here is the routes code I'm using now:
App.OfferRoute = Ember.Route.extend({
model: function (params) {
return App.Offer.find(params.offer_id);
},
setupController: function (controller, model) {
controller.set('content', model);
controller.set('offerTemplates', App.OfferTemplate.find());
controller.set('contentBlockTemplates', App.ContentBlockTemplate.find());
},
renderTemplate: function () {
this.render('offer-title', {
into: 'application', outlet: 'page-title' });
this.render('offer-content', {
into: 'application' });
}
});
App.OfferIndexRoute = Ember.Route.extend({
model: function () {
return this.modelFor("offer");
},
renderTemplate: function () {
this.render('offer-title', {
into: 'application', outlet: 'page-title' });
this.render('offer-content', {
into: 'application' });
}
});
App.OfferEditRoute = Ember.Route.extend({
renderTemplate: function () {
this.controllerFor("offer").set("editMode", true);
this.render('offer-edit-title', {
into: 'application', outlet: 'page-title', controller: 'offer' });
this.render('offer-edit', {
into: 'application', controller: "offer" }); //
}
})