Ike*_*Ike 17 ember.js ember-router
这是了解Ember路线的后续行动.
主/详细视图很棒,但我正在尝试使用分层URL路由而不嵌套模板.但是,对于像痕迹链接和其他引用这样的东西,我仍然需要访问父模型.
所以/users/1/posts应该显示用户1的帖子列表.并且/users/1/posts/1应该为用户1显示帖子1,但它不应该在user模板内部呈现{{outlet}}.相反,它应该完全取代user模板.但是,我仍然需要访问post模板中的当前用户,以便我可以链接回用户,显示用户的姓名等.
首先我尝试了这样的方法(方法#1):
App.Router.map(function() {
this.resource('user', { path: '/users/:user_id' }, function() {
this.resource('posts', function() {
this.resource('post', { path: '/:post_id' });
});
});
});
...
App.PostRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
},
renderTemplate: function() {
this.render('post', {
into: 'application'
});
}
});
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,这将user模板替换为模板post.但是,当我单击浏览器的后退按钮时,user模板不会再次渲染.显然,后视图被销毁但父视图未被重新插入.这里有几个问题提到这一点.
然后我让它用这样的东西(方法#2):
App.Router.map(function() {
this.resource('user', { path: '/users/:user_id' }, function() {
this.resource('posts');
this.resource('post', { path: '/users/:user_id/posts' }, function() {
this.resource('post.index', { path: '/:post_id' });
});
});
...
App.PostRoute = Ember.Route.extend({
model: function(params) {
return App.User.find(params.user_id);
},
setupController: function(controller, model) {
controller.set('user', model);
}
});
App.VideoIndexRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
}
});
App.PostIndexController = Ember.ObjectController.extend({
needs: 'post'
});
Run Code Online (Sandbox Code Playgroud)
但这对我来说似乎有些苛刻而且不是很干.
首先,我需要User再次检索PostRoute并将其作为ad-hoc变量添加到PostController(如果路由正确嵌套并且我可以在其中设置needs: 'user'属性,则不需要这样做PostController).此外,这可能会或可能不会对后端产生影响,具体取决于ember-data的适配器实现或用于从服务器检索数据的任何技术(即,它可能导致不必要的第二次调用加载User).
我还需要一个额外的`PostIndexController'声明来添加新的依赖项,这不是什么大问题.
另一件感觉不对的是/users/:user_id/posts在路由器配置中出现两次(一个嵌套,一个不嵌套).
我可以处理这些问题但它确实有效,但我想,总的来说,这似乎是强迫而不是优雅.我想知道我是否缺少一些明显的配置,这些配置可以让我使用常规嵌套路由,或者如果有人建议更多的"Ember.js方式"这样做.
我应该提一下,不管方法#2的技术优点如何,我花了很长时间才弄清楚如何使它工作.它需要大量的搜索,阅读,试验,调试等才能找到合适的路径定义组合.我认为这不是一个非常独特的用例,用户可以非常直接地设置这样的东西,而无需花费数小时的试验和错误.如果最终成为正确的方法,我会很乐意在Ember.js文档中写下一些提示.
感谢@spullen澄清这一点.我的情况并不像示例那么简单,因为有些子路径需要嵌套模板而有些不需要,但答案帮助我解决了问题.我的最终实现看起来像这样:
App.Router.map(function() {
this.resource('users', { path: '/users/:user_id' }, function() {
this.resource('users.index', { path: '' }, function() {
this.resource('posts')
});
this.resource('post', { path: '/posts/:post_id' }, function() {
this.resource('comments', function() {
this.resource('comment', { path: '/:comment_id' });
});
});
});
});
Run Code Online (Sandbox Code Playgroud)
所以现在posts渲染users模板,但post替换了一切.comments然后呈现下post和comment,反过来,下呈现comments.
所有这些都是子路径,users因此所有人都可以访问用户模型而无需杂技,可以this.modelFor('users')在需要的每个路径中进行.
所以模板看起来像这样:
users
|- posts
post
|- comments
|-comment
Run Code Online (Sandbox Code Playgroud)
我不知道为什么{ path: '' }需要对users.index资源的定义,但如果我把它拿出来余烬未找到users路径.我很想摆脱最后的遗迹.
您可以将父模板定义为仅显示插座并具有将在其中显示的索引路径.然后,对于嵌套资源,您可以执行相同的操作.
<script type="text/x-handlebars" data-template-name="user">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="user/index">
<h2>user/index</h2>
</script>
<script type="text/x-handlebars" data-template-name="posts">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="posts/index">
<h2>posts/index</h2>
</script>
Run Code Online (Sandbox Code Playgroud)
这样它就不会成为主人/细节.
路由器将是:
App.Router.map(function() {
this.resource('user', function() {
this.resource('posts', function() { });
});
});
Run Code Online (Sandbox Code Playgroud)
然后,如果您需要获取有关您可以使用的父级的信息modelFor.所以,如果你在职位,你可以做this.modelFor('user');
这是一个演示这个的jsbin.
希望这是有帮助的.
| 归档时间: |
|
| 查看次数: |
3599 次 |
| 最近记录: |