Ember JS和Ember Rails中的嵌套路线

Gor*_*ter 7 ember.js ember-rails

有人可以用非专业人的术语解释嵌套出口在ember模板中的工作方式吗?

特别是从文档中了解这一点:http: //emberjs.com/guides/routing/rendering-a-template/

"直接的父母路线没有进入主要出口..."

这意味着当前路由尝试呈现到父路由的模板中,但父路由未呈现模板,或者,如果确实如此,则父路由提供的模板未呈现到主模板中(即,默认{{outlet}}).

更具体地说,我正在尝试了解如何在我的应用程序中创建嵌套视图层次结构.它是三层深的收藏品.我想根据集合的内容创建一系列可折叠的嵌套视图.数据结构可以是树状的.

图书馆 - >每个图书馆都有很多图书 - >每本图书都有很多图书

寻找在实践中演示嵌套模板结构的说明性jsbin或代码示例.

想象一下这样的路由器:

App.Router.map(function() {

    this.resource('libraries', function() {
        this.route('new');

        this.resource('library', {path: ':library_id'}, function() {

            this.resource('books', function() {
                this.route('new');
                this.resource('book', {path: ':book_id'}, function() {

                    this.resource('pages', function() {
                        this.route('new');
                        this.resource('page', {path: ':page_id'}, function() {

                        }); // Page
                    }); // Pages

                }); // Book
            }); // Books

        }); // Library
    }); // Libraries

}); // map
Run Code Online (Sandbox Code Playgroud)

Dar*_*kar 9

通常,大多数模板语言提供了一些将target页面内容包装到主布局中的方法.这允许将公共页面布局分离为另一个文件,将较小的目标模板分离到不同的文件中.

在Ember中已经进行了一些迭代,目前这个功能由{{outlet}}助手提供.Outlets是Ember yield进入布局的方式.

outletyield嵌套明显不同的区域.在服务器端屈服更简单.您只需要标记要生成的模板区域,然后调用以将一块内容生成到该指定目标中.

然而,当内容的呈现切换到客户端javascript时,仅按需更新页面的一部分.您不能再yield直接进入标记.你需要一个更聪明的东西yield: - outlet.

有2个方面{{outlet}}.

  1. 一个标记,指示您要产生的位置.这是{{outlet}}帮手.
  2. 将模板呈现到此插座的代码.这是钩子render内部使用的方法renderTemplate.

默认情况下,{{outlet}}不需要名称.这使它成为该模板的默认出口.模板中可以有许多这样的插座,可以通过给它命名来指定它们.例如: -

{{outlet 'sidebar'}}
{{outlet 'nav'}}
Run Code Online (Sandbox Code Playgroud)

这声明了2个名为"sidebar"和"nav"的出口.您现在可以将其他模板渲染到这些插座中.

在没有明确插座名称的情况下渲染时使用默认插座.对于命名出口,渲染是通过调用rendera的renderTemplate钩子来完成的Route.您可以通过outlet在传递给render方法的哈希中指定选项作为选项来执行此操作.

renderTemplate() {
    this.render('recentPosts', { outlet: 'sidebar' });
}
Run Code Online (Sandbox Code Playgroud)

在这里,模板recentPosts将被渲染到其父模板中名为"sidebar"的插座中.

当路由嵌套在其他嵌套路由中时,它们将呈现到最近的父出口.如果父资源没有默认插座,则使用它的父节点,依此类推,直到到达application模板.

当你在中声明一个resourcewith this.resource('posts');Router,你会根据约定指出一些东西.

  1. posts使用布局模板渲染路径posts.
  2. (可选)posts.index使用模板呈现隐式路径posts/index.

posts模板包含所有帖子共有的布局及其子资源.至少它必须包含至少一个默认出口,如,{{outlet}}.

如果没有这个{{outlet}}孩子,路线就不会有直接的父母出口.然后,他们将在父母的父母或最终application模板的出口处进行渲染.发生这种情况时,您将看到"The immediate parent route did not render into the main outlet ..."警告.检查outlets发生这种情况时的位置.

posts.index是给所有具有嵌套路由的资源的隐式路由.换句话说,如果您的资源具有嵌套路由,则不需要显式声明嵌套的this.route('index`).

index路由可以显示该资源的内容.例如,对于posts.index,您可以显示所有列表posts.这个隐含路线的一个次要警告是模型在父posts路线上.你必须使用needsapi来获得这个模型PostsIndexController.

needs: ['posts'],
contentBinding: 'controller.posts'
Run Code Online (Sandbox Code Playgroud)

此外,该posts.index路线是可选的.您可以将UI posts/index用于显示帖子列表,直接显示在posts模板本身中.但是,这意味着任何子资源也将使用帖子列表和插座旁边的列表进行渲染posts.是否使用显式索引路由的决定取决于需要显示的UI.

位于所有其他模板之上的是application模板.它必须具有outlet用于呈现的嵌套资源,并且通常将包含页面共有的布局.如果未指定应用程序模板,则将使用默认模板.这个生成的模板相当于{{outlet}},即: - 只有默认出口的模板.

请考虑以下路线.

App.Router.map(function() {
    this.resource('posts', function() {
      this.route('new')
      this.resource('post', {path: ':post_id'}, function() {
        this.resource('comments', function() {
          this.route('new');
        });
      });
    });
});
Run Code Online (Sandbox Code Playgroud)

这里,posts.new将被渲染成posts将被里面呈现posts,这将被渲染到application模板的默认出口.使用的其余模板如下所示.

+---------------------------+--------------------------------------------------------+
| Route                     | Templates used (default outlets)                       |
+---------------------------+--------------------------------------------------------+
| posts.index               | posts.index > posts > application                      |
+---------------------------+--------------------------------------------------------+
| posts.new                 | posts.new > posts > application                        |
+---------------------------+--------------------------------------------------------+
| posts.post.index          | post.index > post > posts > application                |
+---------------------------+--------------------------------------------------------+
| posts.post.new            | post.new > post > posts > application                  |
+---------------------------+--------------------------------------------------------+
| posts.post.comments.index | comments.index > comments > post > posts > application |
+---------------------------+--------------------------------------------------------+
| posts.post.comments.new   | comments.new > comments > post > posts > application   |
+---------------------------+--------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

可以通过指定方法的into选项来更改此默认模板层次结构render.

renderTemplate: function() {
  this.render('posts', { into: 'sidebar' })
}
Run Code Online (Sandbox Code Playgroud)

此处posts模板将呈现为模板的默认出口sidebar.

就是这样.Outlet是另一个使用大量约定优于配置的余烬概念.默认设置非常好,同时易于自定义.