【问题标题】:Ember js: Render Nested Navigation Sidebar together with a main viewEmber js:将嵌套导航侧边栏与主视图一起呈现
【发布时间】:2014-06-28 18:27:34
【问题描述】:

我有一个页面,其布局如下所示: 左侧有一个嵌套导航。在这种情况下,它显示:

  • 库列表(l1、l2、l3)。目前已选择 l1
  • 图书馆 (1) 中的书籍列表 (b1, b2)
  • 书中包含的页面列表(p1、p2、p3)

如果选择了图书馆,则显示图书馆中书籍的列将自动更新。选择一本书时,页面列将自动更新为该书中的所有页面等...

除此之外,还有一个主视图,它显示当前选定实体的其他详细信息。在这种情况下第 2 页(p2):

 ________________________________
|*l1 | b1 | p1 |                 |
|----|----|----|                 |
| l2 |*b2 |*p2 |  Main View      |
|----|----|----|  (p2 details)   |
| l3 |    | p3 |                 |
 --------------------------------

这是仅选择库时的附加视图。它会在侧边栏中显示所选图书馆、该图书馆中的所有书籍,并在主视图中显示有关该图书馆的详细信息。

 ________________________________
|*l1 | b1 |                      |
|----|----|                      |
| l2 | b2 |       Main View      |
|----|----|       (l1 details)   |
| l3 |    |                      |
 --------------------------------

或者当只选择一本书时:

 ________________________________
|*l1 | b1 | p1 |                 |
|----|----|----|                 |
| l2 |*b2 | p2 |  Main View      |
|----|----|----|  (b2 details)   |
| l3 |    | p3 |                 |
 --------------------------------

因此,例如选择库时,主要有两个工作:

  • 显示图书馆中的所有书籍(导航)
  • 显示有关所选库(主)的详细信息

通过以下方式使用嵌套路由时,导航本身可以正常工作:

Router.map(function() {
  this.resource('libraries', { path: '/libraries' }, function() {
    this.resource('books', { path: ':library'}, function() {
      this.resource('pages', { path: ':book'});
    });
  });
});

在 pages 路由中,我只获取所选图书馆的所有书籍并将其渲染到侧边栏出口:

export default Ember.Route.extend({
  model: function (params) {
    return this.store.find('book', {song: params.library});
  },
  renderTemplate: function() {
    this.render({ outlet: 'sidebar-books' });
  }
});

但是,现在我在尝试将有关当前所选图书馆、书籍或页面的详细信息呈现到主视图和侧边栏视图时遇到了困难。

我发现我可以向renderTemplate 函数添加一个额外的render 调用,这让我可以将其他内容呈现到主视图,但是我不知道如何检索我想从中显示的实体商店,因为不会调用任何其他路线。

为什么要这样做?

【问题讨论】:

    标签: ember.js


    【解决方案1】:

    经过相当多的尝试和错误,在同一条路线中加载两个模型并使用该模型渲染两个视图似乎可以解决问题。

    这是书籍路线。

    路线/books.js:

    export default Ember.Route.extend({
      model: function (params) {
        return Ember.RSVP.hash({
          books: this.store.find('book', {library: params.library}),
          library: this.store.find('library', params.library)
        })
      },
      renderTemplate: function(controller, model) {
        this.render('books',{
          outlet:'sidebar-books'
        });
        this.render('library');
      }
    });
    

    在车把模板中,我现在可以通过以下方式访问库:

    {{library.name}}
    

    并通过以下方式遍历书籍:

    {{#each books}}
      <div class="book">
        <div>{{title}}</div>
      </div>
    {{/each}}
    

    【讨论】:

      【解决方案2】:

      带有动态菜单的侧边导航 用更接近codeySmurf描述的嵌套路由渲染侧边菜单导航示例,虽然加载多个模型的主要问题没有解决,但codeySmurf已经解决了。

      http://emberjs.jsbin.com/begewoza/1/edit

      带有静态菜单的侧边导航

      与内容一起呈现侧边栏菜单的方法可能类似于以下内容。假设不需要在主视图区域中渲染父模型和子模型(例如同时在 book1 下方和 page1 下方显示 lib1 的顶部)并且可以在模板中定义菜单,因此没有嵌套资源已被使用。菜单已通过使用 render 帮助器呈现,尽管也可以使用 named outlets(命名插座示例 http://emberjs.jsbin.com/nibikufa/1/edit)。

      http://emberjs.jsbin.com/hituxado/1/edit

      js

      App = Ember.Application.create();
      
      App.Router.map(function() {
        this.route("allLibraries",{path:"/libraries"});
        this.resource("library",{path:"/libraries/:library"});
        this.resource("book",{path:"/libraries/:library/books/:book"});
        this.resource("page",{path:"/libraries/:library/books/:book/pages/:page"});
      });
      
      
      App.IndexRoute = Ember.Route.extend({
        redirect:function(){this.transitionTo("allLibraries");}
      });
      
      App.LibraryRoute = Ember.Route.extend({
        model:function(params){
          return {libId:params.library};
        }
      });
      
      App.BookRoute = Ember.Route.extend({
        model:function(params){
          return {libId:params.library,bookId:params.book};
        }
      });
      
      App.PageRoute = Ember.Route.extend({
        model:function(params){
          return {libId:params.library,bookId:params.book,pageId:params.page};
        }
      });
      
      App.MenuView = Ember.View.extend({
      
      });
      

      hbs

      <script type="text/x-handlebars">
          <h2> Welcome to Ember.js</h2>
          <div style="float:left">{{render "menu"}}</div>
          <div style="float:left;margin-left:30%">{{outlet}}</div>
        </script>
      
        <script type="text/x-handlebars" data-template-name="allLibraries">
      all libs
        </script>
        <script type="text/x-handlebars" data-template-name="library">
      the library {{libId}}
        </script>
        <script type="text/x-handlebars" data-template-name="book">
      the book {{libId}} - {{bookId}}
        </script>
        <script type="text/x-handlebars" data-template-name="page">
      the page {{libId}} - {{bookId}} - {{pageId}}
        </script>
      
        <script type="text/x-handlebars" data-template-name="menu">
      {{#link-to "allLibraries"}}all libs{{/link-to}}
      <br/>
      {{#link-to "library" 1}}lib 1
      <br/>
      {{#link-to "book" 1 1}}book 1
      <br/>
      {{#link-to "page" 1 1 1}}page1{{/link-to}}
      {{/link-to}}
      <br/>
      {{#link-to "book" 1 2}}book 2
      <br/>
      {{#link-to "page" 1 2 2}}page2{{/link-to}}
      {{/link-to}}
      
      {{/link-to}}
      <br/><br/>
      {{#link-to "library" 2}}lib 2
      <br/>
      {{#link-to "book" 2 2}}book 2
      <br/>
      {{#link-to "page" 2 2 2}}page2 2{{/link-to}}
      {{/link-to}}
      {{/link-to}}
      
      
      
        </script>
      

      css

      a.active{
        background-color:lightgrey;
        border-radius:4px;
        margin:8px;
        padding:4px;
      }
      

      【讨论】:

      • 感谢您的详细回答。可能我的问题不够准确,但是如果选择了图书馆,则需要将书籍列替换为来自一个图书馆的书籍。选择特定书籍时的页面相同。我已经更新了我的问题,以使这一点更清楚。我决定使用嵌套路由来实现这一点,但现在的问题是我需要在调用单个路由时渲染图书馆的详细信息以及图书馆中的所有书籍。这对于非嵌套路由是否可行?
      • 嗯,听起来这可能是我需要采取的路线:stackoverflow.com/questions/20521967/…
      • @codeySmurf 您提到的线程是一个非常好的线程,但它是关于加载多个模型的。您提到的问题是关于动态呈现侧面导航,对吗?我提供的解决方案被简化了,展示了如何使用结构固定的侧导航来布局。如果您将侧边菜单的模板替换为从路由(即 LibraryRoute、BookRoute、PageRoute 等)检索到的模型的内容,它将按您的需要工作。
      • 我不确定我是否理解正确。我想我需要为一条路线加载两个模型:如果选择了图书馆,我需要加载图书馆本身以及与该图书馆关联的书籍列表。然后,我需要在侧边栏中呈现书籍列表(连同先前获得的图书馆列表)以及在主视图中有关图书馆的详细信息。可能有更好的方法来做到这一点,我目前只是不太了解......
      • @codeySmurf 太棒了!尽管我造成了一些混乱,但为此 +1 :) 。你的解决方案很好。我的方法并不是更好,这只是另一种解决方案,恐怕不是您想要的。我认为您在组合路由和渲染部分时遇到了麻烦,而您实际上已经弄清楚了,并且您主要需要加载多个模型。所以我会继续清理一切,以防任何用户登陆这里寻找侧边菜单功能。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 2013-01-20
      • 2017-07-02
      • 2014-07-03
      相关资源
      最近更新 更多