Ember JS和Ember Rails中的嵌套路线

时间:2013-07-15 19:59:09

标签: 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

1 个答案:

答案 0 :(得分:9)

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

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

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

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

{{outlet}}有两面。

  1. 表示您想要屈服的标记。这是{{outlet}}助手。
  2. 将模板呈现到此插座的代码。这是render挂钩中使用的renderTemplate方法。
  3. 默认情况下,{{outlet}}不需要名称。这使它成为该模板的默认出口。模板中可以有许多这样的插座,可以通过给它命名来指定它们。例如: -

    {{outlet 'sidebar'}}
    {{outlet 'nav'}}
    

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

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

    render

    此处,模板renderTemplate() { this.render('recentPosts', { outlet: 'sidebar' }); } 将呈现在其父模板中名为“sidebar”的插座中。

    当路线嵌套在其他嵌套路线中时,它们将渲染到最近的父路径。如果父资源没有默认插座,则使用它的父节点,依此类推,直到达到recentPosts模板。

    当您在application中声明resource this.resource('posts');时,您会根据惯例指出一些内容。

    1. 使用布局模板Router呈现posts路线。
    2. (可选)使用模板posts呈现隐式posts.index路由。
    3. 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 api才能在needs

      中获得此模型
      PostsIndexController

      此外,此needs: ['posts'], contentBinding: 'controller.posts' 路由是可选的。您可以将用于显示帖子列表的posts.index用户界面直接放入posts/index模板本身。但是,这意味着任何子资源也将使用posts中的插座旁边的帖子列表进行渲染。是否使用显式索引路由的决定取决于需要显示的UI。

      位于所有其他模板之上的是posts模板。它必须具有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'); }); }); }); }); 将呈现为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 | +---------------------------+--------------------------------------------------------+ 模板的默认出口中。使用的其余模板如下所示。

      into

      可以通过为render方法指定renderTemplate: function() { this.render('posts', { into: 'sidebar' }) } 选项来更改此默认模板层次结构。

      posts

      此处sidebar模板将呈现为Outlet模板的默认出口。

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