问题
The code
I'm using the version 4fcdbf2560 with the new router.
In my application, a user can be authenticated or not. The rendered template will not be the same depending on the authentication state.
I've manage this by redefining the function renderTemplate
in the ApplicationRoute
:
App.ApplicationRoute = Ember.Route.extend({
renderTemplate: function() {
this.render(App.authenticated() ? 'authenticated' : 'unauthenticated');
}
});
My router is quite simple:
App.Router.map(function(match) {
match('/').to('index');
match('/sign').to('sign', function(match) {
match('/in').to('signIn');
});
match('/dashboard').to('dashboard');
});
The IndexRoute
is just here to redirect the user depending on the authentication state:
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo(App.authenticated() ? 'dashboard' : 'signIn');
}
});
The workflow
- A user navigates to
/
- The
ApplicationRoute
is entered, as the user is not authenticated, theunauthenticated
template is rendered - The
IndexRoute
is entered, as the user is not authenticated, a redirection is made tosignIn
- The
signIn
template is rendered into its parent template -> theunauthenticated
template - The user sign in successfully,
route.transitionTo('dashboard')
is called - The
dashboard
template is rendered into its parent template -> theunauthenticated
template
The questions
- What's wrong with my implementation ?
- Why does the
renderTemplate
function is not called when thedashboard
template is rendered ? - How can I force the application to re-render its template ?
Edit 2013-01-07
I've modified my code according to Evan's answer.
My application template now looks like this:
{{#if isAuthenticated}}
<h1>Authenticated</h1>
{{outlet}}
{{else}}
<h1>Unauthenticated</h1>
{{outlet}}
{{/if}}
When the user lands on the application page, as he's not authenticated, it's the unauthenticated block which is rendered. Everything is working well except that nothing render into the {{outlet}}
tag...
But when my application template looks like this (=without conditional tags):
<h1>Unauthenticated</h1>
{{outlet}}
...it works ! So I wonder if the {{outlet}}
tag can be inserted between conditional tags.
回答1:
I think it might be a mistake to have this logic in the Router; Instead this should be part of the ApplicationController.
Since ember will automatically update the templates as application state changes you can create an ApplicationController that tracks the authentication state
App.ApplicationController = Ember.Controller.extend({
isAuthenticated: null
});
And construct your templates like this:
<script type="text/x-handlebars" data-template-name="application">
{{ #if isAuthenticated }}
You are now logged in
{{ else }}
Please Log In
{{ /if }}
</script>
Now you don't actually have to worry about manually updating / rendering the template. As the internal (JS) state changes your template will automatically update to reflect the application state.
回答2:
sly7_7 comment is the answer. See github.com/emberjs/ember.js/pull/1671 for outlet inside blocks.
This has just been merged into master: https://github.com/emberjs/ember.js/pull/1671#issuecomment-11982451
来源:https://stackoverflow.com/questions/14185040/how-to-re-render-application-template-with-new-router