0

我真的很难理解 Ember 中的路由概念,但比看起来更复杂。从文档。只要有不同的 url 或路径,你就会看到你有不同的路由,如果你在同一个 url 中有不同的路径,很容易你只需要创建一个嵌套模板。但是当你在一个 url 中有 3 条不同的路径时呢?

this.resource 和 this.route 有什么区别?

由于活生生的例子总是比纯理论好,这里是我的应用程序。在索引或“/”中,我应该呈现“列表模板”、“新模板”,当用户单击列表链接时,“注释模板”将呈现为“新模板”。

我的路由器:

Notes.Router.map(function () {
  this.resource('index', { path: '/' }, function (){
    this.resource('list', {path: ':note_title'});
    this.resource('new', {path: '/'});
this.resource('note', { path: ':note_id' });
});
});

我的模板:

<script type="text/x-handlebars" data-template-name="index"> 
  <div class="wrap">
    <div class="bar">
    {{input type="text" class="search" placeholder="Where is my bookmark??" value=search action="query"}}

      <div class="bar-buttons">
        <button {{action "addNote"}}> NEW </button>
      </div>
    </div>
    {{outlet}}
  </div> 
</script>

<script type="text/x-handlebars" data-template-name="list">
<aside>
  <h4 class="all-notes">All Notes {{length}}</h4>
    {{#each item in model}}
      <li>
       {{#link-to 'note' item}} {{item.title}} {{/link-to}}
      </li>
    {{/each}}
</aside>
</script>

<script type="text/x-handlebars" data-template-name="new"> 
   <section>
    <div class="note">
      {{input type="text" placeholder="Title" value=newTitle action="createNote"}}
      <div class="error" id="error" style="display:none"> Fill in the Title! </div>

      {{input type="text" placeholder="What you need to remember?" value=newBody action="createNote"}}
      {{input type="text" placeholder="Url:" value=newUrl action="createNote"}}
    </div>
   </section>
 </script>

  <script type="text/x-handlebars" data-template-name="note"> 
    <section>
        <div class="note">
            {{#if isEditing}}
              <h2 class="note-title input-title"> {{edit-input-note value=title focus-out="modified" insert-newline="modified"}} </h2>
              <p class="input-body"> {{edit-area-note value=body focus-out="modified" insert-newline="modified"}} </p>
              {{edit-input-note value=url focus-out="modified" insert-newline="modified"}}
            {{else}}
              <h2 {{action "editNote" on="doubleClick"}} class="note-title" > {{title}} </h2>
              <button {{action "removeNote"}} class="delete"> Delete </button>
              <p {{action "editNote" on="doubleClick"}}> {{body}} </p>
              {{input type="text" placeholder="URL:" class="input"  value=url }}
            {{/if}}
        </div>
      </section>
  </script>

或者这里的 Js Bin: http: //jsbin.com/oWeLuvo/1/edit ?html,js,output

如果需要我的控制器或模型,我也会添加该代码。提前致谢

4

2 回答 2

1

您的示例似乎有效。

你只是错过了依赖。您还没有包含 Handlebars 和 Ember.data

如果你检查了你的 javascript 控制台,你就会看到抛出的错误。

工作示例:http: //jsbin.com/oWeLuvo/2/

于 2013-11-07T16:13:01.767 回答
1

在 Ember 中,资源和路由都是路由。它们有两个名称,以便 Ember 区分什么是资源和路由。老实说,要记住它们都是路线并保持理智,您可以分别将它们称为“资源路线”和“路线”。资源可以嵌套,并且可以在其中嵌套子资源或路由。另一方面,路线不能嵌套任何东西。

如果您还没有使用Ember Inspector ,请安装它。它是一个 chrome 扩展,将帮助您使用 Ember 安装到 Chrome Web 浏览器中的路由、控制器、模板、数据和许多其他东西。我听说的最后一个 Ember Inspector 也可以在 FireFox 开发工具中使用。https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi?hl=en

因此,如果有资源,您可以嵌套资源和路由。嵌套资源将保留其名称空间,路由将附加到嵌套名称空间。请记住,您不能在路由中嵌套任何内容。

 App.Router.map(function() {
   //creating a resource
   this.resource('foo', {path: 'somePathYouPut'}, function() {
     //nesting stuff inside of the resource above

     //could open another nest level here in bar if you want
     this.resource('bar');

     //can not nest in route. Sad face. Sorry
     this.route('zoo');
   });
 });

由于您不能将任何内容嵌套到路由中,因此index模板中的 {{outlet}} 没有任何要查找的子节点,并且默认情况下会渲染到该 {{outlet}} 中。我相信这就是你认为会发生的事情。

 <script type="text/x-handlebars" data-template-name="index"> 
   <div class="wrap">
     <div class="bar">
       {{input type="text" class="search" 
         placeholder="Where is my bookmark??" value=search action="query"}}

     <div class="bar-buttons">
     <button {{action "addNote"}}> NEW </button>
    </div>
  </div>
  {{outlet}}
 </div> 
</script>

在您的代码中,您将其index称为资源,它是一条路线。由于索引是一个路由,记住你不能在路由中嵌套元素,你的代码应该看起来更像这样。您resource的“新”路径/也可以删除。

 Notes.Router.map(function () {  
   //this is a route not a resource you had it as resource 
   //and tried to nest in your code
   this.route('index', { path: '/' });
   this.resource('list', {path: ':note_title'});
   this.resource('new');
   this.resource('note', { path: ':note_id' });
 });

index从来自应用程序级别的最顶层开始在每个嵌套级别获得一个,但您不必在路由器中明确定义它们它们就在那里。您在每个嵌套级别免费获得的index路由默认情况下与其直接父级关联,并默认呈现到其父级“出口”。你可以认为路由器看起来像这样。

仅用于说明目的:

Notes.Router.map(function() {
  //think of this as your application level stuff that Ember just does!!
  //this is not written like this but to illustrate what is going on
  //you would get application template, ApplicationRoute, ApplicationController
  this.resource('application', function() {

    //this is an index that you get for free cause its nested
    //its that index template, IndexController, and IndexRoute you were using
    this.route('index', { path: '/' });

    this.resource('foo', {path: 'somePathYouPutHere' }, function() {
      //since you started another nested level surprise you get another `index`
      //but this one is `foo/index` template.
      this.route('index', {path: '/'});
      this.route('zoo');
    });
  });
});

上述夸张的路由器示例的第一部分,Ember 会在幕后自动执行,这是您所听说的“魔法”的一部分。它做了两件事,它为自己设置了一个应用程序环境,你得到ApplicationRoute,ApplicationController和一个总是在幕后的application模板。其次,它使您获得IndexRoute 和一个您可以使用或忽略的模板。因此,如果您什么都不做,没有其他代码在文件中声明和 Ember App,打开 Ember Inspector 并查看路由,您将看到上述资产。indexIndexControllerindexvar App = Ember.Application.create();

现在,foo上述路由器中的资源是您将要创建的资源的一个示例,并且正如您所看到的index,因为您开始嵌套,所以您在那里获得了一个资源。如上所述,您不必在每个嵌套级别定义索引,this.route('index', {path: '/'});从内部foo可以完全省略,Ember 仍然会做同样的事情。你最终会得到foo/index模板,FooIndexRoute以及FooIndexController预期的foo模板,FooRoute和 FooController . You can think of thefoo index as a place that says 'hey' before anything else gets rolled into my parentfoo` 并被渲染如果你愿意,我可以展示一些东西,使用我。

这也是一个很好的时机来强调当你在资源中嵌套路由时命名空间会发生什么,就像this.route('zoo')上面的例子一样。路由的命名空间zoo现在将被附加到资源中foo,您最终会得到foo/zoo模板FooZooRoute和一个FooZooController.

如果您要将 zoo 更改为嵌套在 foo 资源中的资源this.resource('zoo');,则命名空间将保留给 zoo。您最终会得到“动物园”模板ZooRoute和一个ZooController. 名称空间被保留。好的,足够的侧面跟踪您的应用程序。

您说您希望/应用程序的 url 呈现list template. 为了实现这一点,您必须覆盖 Ember 启动时发生的默认行为。/您可以通过将 添加{path: '/'}到路由器中的第一个资源或路由来覆盖顶层。从上面的假路由器代码中,您获得的第一index条路由与应用程序相关联。默认情况下,如果您什么都不做,Ember 会将该index模板推送到application模板中。但是,当您为您的应用程序点击 ' 的基本 url 时,这不是您希望将list模板推送到应用程序模板中的内容/

Notes.Router.map(function() { 
  this.resource('list', {path: '/'});
  this.resource('new');
  this.resource('note', { path: ':note_id' });
});

通过像我在上面所做的那样将代码添加{path: '/'}到第一个资源中,您现在告诉 Ember 当我的应用程序 url 到达基本 url/或当您启动时使用我的列表模板而不是您的默认index模板并将其呈现到应用程序模板中. 此外,由于当您的应用程序通过 url 转换到这些路由时,其他资源没有嵌套,所以它们会破坏应用程序模板 {{outlet}} 中的内容并在其中替换自己。

您提到在路由中定义“路径”的作用是告诉 Ember 您希望如何在 url 中表示该路由。在上面的示例中,如果您保持新资源不变,Ember 默认将使用路由名称作为路径,url 将是/new. 您可以在新资源的路径中放置任何名称,this.resource(new, {path :'emberMakesMeKingOfWorld'});该名称将在 url 中表示为,/emberMakesMeKingOfWorld并且该长内容仍将与您的新路由相关联。您的用户可能会对这个 url 的含义感到困惑,但在幕后您会知道它与您的新路线相关联。这只是一个示例,但使用描述性名称可能是一种很好的做法,这样您的用户就知道在您的应用程序中点击 url 意味着什么。

在覆盖index与应用程序关联的默认模板之后。我将您的代码移到了应用程序模板中。其原因似乎是您希望始终显示带有“newNote”操作的那个栏。如果你想在你的应用程序中一直存在一些东西,比如导航栏、页脚,我相信你能想到更好的东西,把它放在应用程序模板中。

这是一个 JSBIN,我稍微调整了你的代码

http://jsbin.com/oWeLuvo/8

我希望这有助于快乐编码。

于 2013-11-07T19:16:25.947 回答