在Ember.js中组织列表,查看,创建和更新路由的最佳实践

时间:2018-06-22 16:33:48

标签: ember.js software-design

现在与ember.js一起工作了几年,对我来说还不是很清楚,应该将什么作为构造列表,查看,创建和更新路由的最佳实践。

到目前为止,我参与的项目主要用于为每个实体路由树。用于创建的带有子路由的列表的复数实体名称,以及带有用于编辑的子路由的详细视图的单数实体名称。例如,一个post模型将具有以下这些路线:/posts用于列出帖子,/posts/new用于创建功能,/post/:post_id用于显示单个帖子,而{{1} }进行编辑。相应的路由器如下所示:

/post/:post_id/edit

这种方法对于细节和编辑视图非常有效,因为它们共享相同的模型。因此,编辑路径的模型挂钩可以仅重用详细视图路径的模型。在余烬代码中,如下所示:

Router.map(function() {
  this.route('post', { path: '/post/:post_id' }, function() {
    this.route('edit');
  });
  this.route('posts', function() {
    this.route('new');
  });
});

通常,我们将从// app/routes/post.js import Route from '@ember/routing/route'; export default Route.extend({ model({ post_id }) { return this.get('store').findRecord('post', post_id); } }); // app/routes/post/edit.js import Route from '@ember/routing/route'; export default Route.extend({ model() { return this.modelFor('post'); } }); 路由模型钩子中返回帖子的集合,而不实现posts路由的模型钩子(或根据架构返回一个POJO / Changeset,但这不是这里的问题) )。假设我们没有实现posts.new的模型钩子,那么路由将如下所示:

posts.new

但是现在这种方法无法正常工作,导致到// app/routes/posts.js import Route from '@ember/routing/route'; export default Route.extend({ model({ post_id }) { return this.get('store').findAll('post'); } }); // app/routes/posts/new.js import Route from '@ember/routing/route'; export default Route.extend({ }); 路由的转换被阻止,直到加载posts.new的集合为止。由于我们不需要此集合来创建帖子列表(至少如果仅在posts路线中而不是在所有子路线中显示它们),感觉不对。

对那些不熟悉ember的人的注释:嵌套的路由模型钩子按顺序执行。因此,在我们的案例中,首先是应用程序路由的模型钩子,然后发布路由,然后发布.new路由,以等待其中一个执行的诺言。

那么什么才是最佳实践呢?

  • 如果我们不在嵌套路线上显示帖子,则应该在posts.index路线中保存帖子吗?
  • 创建路线不是嵌套在列表路线下方吗?那么我们应该有posts.indexpostspost-newpost路线吗?由于与邮政相关的代码被划分为三个路由树,因此感到困惑。由于代码将分为三个目录,因此也有悖于improved file layout当前开发的目标。
  • 我们是否应该权衡取不必要的帖子集合,因为大多数用户流是在创建路径之前来自此路径的,因此模型钩子在大多数情况下已经加载了?

希望您对此有任何想法。决定不要在社区闲暇时问这个问题,以更好地记录答案。

1 个答案:

答案 0 :(得分:3)

在余烬中使用nested route的主要目的是将子路线的输出嵌套在父路线中。尽管您当前的结构有效,但它实际上与ember具有结构化路由功能的方式并不匹配。

您应使用具有明确定义的index route的单数嵌套路由。

  

在每个嵌套层(包括顶层),灰烬   自动为/名为index的路径提供路由。看什么时候   出现新级别的嵌套时,每当您看到一个   功能,这是一个新的水平。

Router.map(function() {
  this.route('posts', function() {
    this.route('favorites');
  });
});

等效于

Router.map(function() {
  this.route('index', { path: '/' });
  this.route('posts', function() {
    this.route('index', { path: '/' });
    this.route('favorites');
  });
});

如果您创建一个明确的posts / index.js文件,则可以将其用作您的列表路径。这样做可以帮助您避免在过渡到创建路线之前提取所有帖子的问题。

尽管与您目前的结构不同,我建议以下内容。

Router.map(function() {
  this.route('posts', function() {
      this.route('index');  // /posts  - posts/index.js
      this.route('new');    // /posts/new - posts/new.js
      this.route('view', { path: '/:post_id' }  // /posts/1234 - posts/view.js
      this.route('edit', { path: '/:post_id/edit' }  // /posts/1234/edit - posts/edit.js
  }); 
});

根据新建和编辑中逻辑的复杂性,您可以考虑将两条路径合并为一条,或者在生成空模型后简单地将新路径转换为编辑。

这样做的好处包括:

简单性 您不必为所有路线重新定义路径。一切都在posts /下,并且路线指定了下一块。

一致性 JSONapi模式使用plural routes来获取集合和单个对象。

逻辑包装 如果使用显式index.js文件,则可以将旧的posts.js文件用作post名称空间中所有项目的通用包装。 Posts.js将有一个出口,将索引,新建,编辑和查看路线放入其中

如果您需要视图和编辑路径来共享相同的模型生成,则可以将视图/编辑嵌套到一个公共组中,以便它们共享父模型。

this.route('posts', function() {
    this.route('post', { path: '/:post_id' }, function() {
        this.route('view', { path: '/' }) ;
        this.route('edit', { path: '/edit' });
    })
})