My page layout (application template) looks like this (simplified):
I use it for different routes (offer list + offer detail, customer list + customer detail). Lists are shown in the sub-navigation outlet.
My router's code:
App.Router.map(function () {
//...
this.resource('offers', function () {
this.resource('offer', { path: '/:offer_id' });
});
}
My Routes:
App.OffersRoute = Ember.Route.extend({
model: function () {
return App.Offer.find();
},
renderTemplate: function (controller, model) {
this.render('offer-list', {
into: 'application', outlet: 'sub-navigation', controller: 'offers' });
this.render('offer-list-title', { into: 'application', outlet: 'page-title' });
this.render('offer-list-content', { into: 'application' });
}
});
App.OfferRoute = Ember.Route.extend({
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' });
}
});
Now this works so far.
http://.../#/offers
shows the list and the title "Offer summary" and static html content. I click on one of the offers in the list, going to
http://.../#/offers/23
all okay: it still shows the list of offers in the sub-navigation area and the correct title and the content of the offer.
Now my problem:
If I return to the
http://.../#/offers
page (using a #linkTo helper on a menu), then the {{outlet}} / content area becomes empty (not the static html from before) and the title is still the title in {{page-title}} of the offer/23 route.
How can I let my app "re-render" the template as defined in the OffersRoute renderTemplate()
?
P.S.: I'm using Ember.js 1.0.0-RC.3
Using the built-in Index
routes and maintaining the ApplicationRoute
-> OffersRoute
-> OfferRoute
hierarchy will solve your issue.
If you turn on the router transition logging you will see that when navigating to Offers
you are actually entering the Offers.Index
route:
App = Ember.Application.create({
LOG_TRANSITIONS: true
});
This means that you can set your static Offers title and set the static Offers content in OffersIndexRoute
and it will be correctly set the first time and set again if you link back to it from inside of an offer detail page. For this to work you also must preserve the ApplicationRoute
-> Offers
-> Offer
{{outlet}}
hierarchy by not directly rendering everything into the ApplicationRoute
's {{outlet}}
. The reason you must preserve this hierarchy is that by rendering the child (Offer
template) directly into the Application
template you remove the Offers
template and when you try to go back to the OffersRoute
its template has been removed and it shows nothing.
Use OffersIndexRoute
to fill in the ApplicationRoute
's {{outlet}}
and the {{outlet page-title}}
.
JS:
//this renders the title and the main content for Offers
App.OffersIndexRoute = Ember.Route.extend({
renderTemplate: function (controller, model) {
this.render('offer-list-title', { into: 'application', outlet: 'page-title' });
this.render();
}
});
App.OffersRoute = Ember.Route.extend({
model: function () {
return App.Offer.find();
},
renderTemplate: function (controller, model) {
this.render('offer-list', {
into: 'application', outlet: 'sub-navigation', controller: 'offers' });
// render this in OffersIndexRoute instead
//this.render('offer-list-title', { into: 'application', outlet: 'page-title' });
this.render('offer-list-content', { into: 'application' });
}
});
Handlebars:
<script type="text/x-handlebars" data-template-name="offer-list-content">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="offers/index">
Offers content
</script>
The outlet in the offers-list-content
will be filled in by the OffersIndexRoute
or by the Offer
template, depending on what the current route is.
{{outlet}}
hierarchyAllow the OfferRoute
to render it's content template into the OffersRoute
template instead of forcing it into the ApplicationRoute
.
App.OfferRoute = Ember.Route.extend({
model: function (params) {
return App.Offer.find(params.offer_id);
},
renderTemplate: function () {
this.render('offer-title', { into: 'application', outlet: 'page-title' });
// preserve the hierarchy and render into the Offers {{outlet}}, which is the default
//this.render('offer-content', { into: 'application' });
this.render('offer-content');
}
});
Working JSBin example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With