javascript - Ember.js v2 路由器中的多个导出

标签 javascript ember.js

我刚刚开始使用 Ember.js,有一件看起来很有前途的事情是将多个 outlet 组合在一起的多个模板混合在一起以生成复杂但模块化的布局的想法。

不过,我无法让它工作。几个月前(2012 年年中)似乎有很多关于此的问题、答案和示例,但在迈向 1.0 的过程中,他们最近(2012 年 12 月/2013 年 1 月)将路由器重写为“v2”API。这些文档很好地描述了它们所描述的内容,但省略了很多大背景,而且我还没有找到一个端到端的示例。

这是我读到的内容:

  • the Routing guide 下的所有内容(最新但不详尽)
  • "outlet" template helper api reference (这可能已经过时了?我每次尝试调用 controller.connectOutlet() 都会失败并返回 Uncaught TypeError: Object <(generated animals.cats controller):ember170> has no method 'connectOutlet'
  • 公告Ember.js Router API v2 .特别是底部的几条评论(多个 channel 的问答)。是的,这个要点被标记为“警告;已过时;有关最新信息,请参阅路由指南”。但是目前的路由指南似乎并没有完全描述这种行为。 Rendering a template指南的一部分展示了如何渲染到已经存在的不同导出(我可以让它工作),但我不知道如何连接额外的导出或实例化额外的模板。

什么对我有用:

  • 设置嵌套路由(嗯,嵌套资源;你不能嵌套路由;但你可以为嵌套资源自定义路由),并嵌套根据路由自动实例化的模板和导出。

我一直无法弄清楚如何完成的事情:

  • 手动实例化模板并将它们连接到 socket 。如果您想使用多个导出,或者如果您想要构建与您的路线不同的导出/模板关系结构,这似乎是必要的。 (下面将有一个这样的例子。基本上我想做的是使用一个模板作为一个混合,我可以将它嵌入到任何我想要的地方。)

看起来很有希望但对我来说失败的事情是

  • 覆盖路由的 Controller (使用 App.WhateverRoute = Ember.Route.extend() 扩展路由,提供我自己的 setupController 方法)并调用 controller.connectOutlet这里。如上所述失败;传入此方法的 Controller 对象没有 connectOutlet方法。

示例 ( here as a jsFiddle ,或下面作为一个独立的 html 文档,它嵌入了 CSS 和脚本并从 https 链接加载 Ember 和依赖项,因此您应该能够只保存到本地文件并在浏览器中打开如果你想尝试一下):

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Ember.js Router Example</title>
    <style>
      .outlet {
        border: 1px solid black;
        padding: 5px;
      }
    </style>
  </head>

  <body>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script src="https://raw.github.com/wycats/handlebars.js/1.0.rc.2/dist/handlebars.js"></script>
    <script src="https://raw.github.com/emberjs/ember.js/release-builds/ember-1.0.0-pre.4.js"></script>


    <script type="text/x-handlebars" data-template-name="index">
      <p>Root index template. You should not see this because we redirect App.IndexRoute elsewhere.</p>
    </script>

    <script type="text/x-handlebars" data-template-name="about">
      <p>About this demo.</p>
    </script>

    <script type="text/x-handlebars" data-template-name="guide">
      <p>Guide to this demo.</p>
    </script>

   <script type="text/x-handlebars" data-template-name="animals">
      <p>Animals. You have selected:</p>
      <div class='outlet'>{{ outlet }}</div>
    </script>

    <script type="text/x-handlebars" data-template-name="animals/index">
      <!-- you will not see this unless you disable App.AnimalsIndexRoute redirect. -->
      <p>No animal selected.</p>
    </script>

    <script type="text/x-handlebars" data-template-name="animals/cats">
      <p>Cat. I can meow. Like all animals, I
        <span class='outlet'>{{ outlet }}</span>
      </p>
    </script>

    <script type="text/x-handlebars" data-template-name="animals/dogs">
      <p>Dog. I can bark. Like all animals, I
        <span class='outlet'>{{ outlet }}</span>
      </p>
    </script>

    <script type="text/x-handlebars" data-template-name="animal_mixin">
      <p>am alive.</p>
    </script>

    <script type="text/x-handlebars" data-template-name="application">
      <div class="container">
        <p>
          Select contents for my outlet:
          {{#linkTo "index"}}/ (root){{/linkTo}}
          {{#linkTo "about"}}/about{{/linkTo}}
          {{#linkTo "guide"}}/guide{{/linkTo}}
          {{#linkTo "animals"}}/animals{{/linkTo}}
          {{#linkTo "animals.cats"}}/animals/cats{{/linkTo}}
          {{#linkTo "animals.dogs"}}/animals/dogs{{/linkTo}}
        </p>

        <div class='outlet'>
          {{ outlet }}
        </div>
      </div>
    </script>

    <script>
      App = Ember.Application.create();
      App.Router.map(function() {
        this.resource("about");
        this.resource("guide");
        this.resource("animals", function() {
          this.route("cats");
          this.route("dogs");
        })
      });
      App.IndexRoute = Ember.Route.extend({
        redirect: function() {
          this.transitionTo('about');
        }
      });
      App.AnimalsIndexRoute = Ember.Route.extend({
        redirect: function() {
          this.transitionTo('animals.cats');
        }
      });
      App.AnimalsCatsRoute = Ember.Route.extend({
        setupController: function(controller, model) {
          // BUG: this controller object has no connectOutlet method
          // (uncomment to see this yourself)
          // controller.connectOutlet('animal_mixin');
        }
      });
      App.initialize();
    </script>

</html>

本质上,animal_mixin 是一大块样板文件,我想将其作为 mixin 重复使用,通过在此处放置一个 socket 并将其连接到此模板,将其放在我想要的任何位置。我意识到这个例子是人为的,因为我可以用嵌套结构提供的“继承”来做到这一点:animal_mixin 的内容可以直接进入“animals”模板,我不需要在 animals/cats 和动物/狗。如果我想在所有动物中使用它,那会很好,但假设我有另一个/animals 子路径,我不想包含此代码段。同样,这个例子是人为设计的,但我希望问题和意图是明确的。

最佳答案

您可以使用多个命名 socket 。这是一个 jsfiddle 示例:http://jsfiddle.net/W2dE4/6/

<script type="text/x-handlebars" data-template-name="application">
    {{outlet header}}
    {{outlet body}}
    {{outlet navBar}}
</script>

另请参阅 this answer 了解一些其他技术。

events: {
    showModal: function(){
        this.render('modal', {
            into: 'index',
            outlet: 'modalOutlet',
            controller: this.controllerFor('modal')
        }); 
    }
}

关于javascript - Ember.js v2 路由器中的多个导出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14531956/

相关文章:

javascript - Ember.js 服务器端或客户端或两者?

javascript - Ember JS 属性访问器

javascript - 在 Javascript 中按值分配

javascript - 将用户输入永久发布到网页

javascript - 为什么 Ember 观察者不对数组开火?

ember.js - 如何将子记录添加到现有父记录?

ember.js - Ember : How can I set bind-attr for a link-to?

Javascript 在输入类型文本上获取按键 "Enter"事件

javascript - 发送带有 header 的 AJAX 请求

javascript - Firestore - 从文档中获取特定字段