ember.js - 用于嵌套路由但非嵌套模板的惯用 Emberjs

标签 ember.js ember-router

这是 Understanding Ember routes 的后续。

主/详细 View 很棒,但我试图在不嵌套模板的情况下创建一个分层 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'
    });
  }
});

正如预期的那样,这用 user 替换了 post 模板。但是当我单击浏览器的后退按钮时,user 模板不会再次呈现。显然 post View 被破坏但父 View 没有重新插入。这里有几个问题提到了这一点。

然后我让它与这样的东西一起工作(方法#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'
});

但这对我来说似乎有点老套,而且不是很干。

首先,我需要在 User 中再次检索 PostRoute 并将其作为临时变量添加到 PostController (如果路由正确嵌套,则不需要这样做,我可以在 needs: 'user' 中设置 PostController 属性)。此外,这可能会或可能不会对后端产生影响,具体取决于 ember-data 的适配器实现或用于从服务器检索数据的任何技术(即,它可能会导致不必要的第二次调用 load 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' });
      });
    });
  });
});

所以现在 postsusers 模板下渲染,但 post 替换了所有内容。 comments 然后在 postcomment 下渲染,依次在 comments 下渲染。

它们都是 users 的子路由,因此所有用户模型都可以在没有杂技的情况下访问,只需在需要的每个 Route 中执行 this.modelFor('users') 即可。

所以模板看起来像这样:
users
|- posts
post
|- comments
   |-comment

我不知道为什么 { path: '' } 资源定义需要 users.index 但如果我把它拿出来,Ember 找不到 users 路由。我很想摆脱最后的痕迹。

最佳答案

您可以将父模板定义为仅显示 socket 并具有将在其中显示的索引路由。然后对于嵌套资源,您可以做同样的事情。

<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>

这样它就不会是一个主/细节。

路由器将是:
App.Router.map(function() {
  this.resource('user', function() {
    this.resource('posts', function() { });
  });
});

然后,如果您需要获取有关父级的信息,您可以使用 modelFor .所以如果你在帖子里,你可以做this.modelFor('user') ;

这是 jsbin这证明了这一点。

希望这会有所帮助。

关于ember.js - 用于嵌套路由但非嵌套模板的惯用 Emberjs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17012806/

相关文章:

javascript - 可从任何地方访问的路线上的 Ember Modal

javascript - emberjs 与 hash 绑定(bind)

ember.js - 在 Ember.js 中的嵌套组件中触发操作

javascript - Ember.js afterModel 钩子(Hook)触发两个相同的请求

ember.js - Ember.Component( block 形式): more than one outlet {{yield}}

javascript - 与 contentscript 的 chrome 扩展中注入(inject)的 ember.js 发生冲突

javascript - Ember.js 过渡渲染错误或错误的路由

javascript - 错误子状态

javascript - 如何从组件中的 sendAction 方法获取返回状态

ember.js - Ember 路由中的查询参数