10

我正在用 EmberJS v1.0.pre 编写一个应用程序。我有一个ArrayController包含所有人的列表。有一堆嵌套视图显示了这个人、他们的宠物以及每只宠物的注释。

|----------------------------------------|
| John                                   | <- Person
|----------------------------------------|
|   Quincy (Dog)                         | <- Pet
|     - Super ornery                     | <- Note
|     - Likes XYZ Dog food               |
|     - Will eat your socks              |
|                                        |
|   Tom (Cat)                            |
|    - Always (not) catching mice        |
|                                        |
|----------------------------------------|
| Roger                                  |
|----------------------------------------|
|   V (Dog)                              |
|    - Likes XYZ Dog food                |
|    - Sneezes, but it's ok              |
|                                        |
|----------------------------------------|
| ...                                    |

从纯 MVC 的角度来看,感觉每个孩子都应该有一个控制器,但我不知道如何在 Ember 中实现这一点。有顶部的 Array 控制器,然后是所有单独的视图。如果我想删除或编辑注释,似乎我需要将视图的上下文传递给控制器​​。

// in the view
click: function () {
  this.get('controller').updateNote(this.get('content'))
}

这对我来说感觉很糟糕,视图不应该是数据的权威来源。我的假设是 ArrayController 会实例itemControlerClassitemViewClass.

更新:我创建了一个小提琴来更好地说明我的问题。该功能是故意不完整的,目的是在单击列表上的项目时通过增加内容来完成功能。

更新:对不起,我意外删除了小提琴!我正在为最终解决方案做一些工作,所以我将尝试使用该解决方案创建一个新的小提琴。

4

4 回答 4

12

“从纯 MVC 的角度来看,感觉应该为每个孩子都有一个控制器”

您不需要为每个项目设置一个控制器,而是为每个对象集合(人物、宠物、便笺)设置一个 ArrayController。顺便说一句,对子对象(狗、笔记)的任何操作都不应该传递给App.PersonsController. 这将打破关注点分离原则。

Ember.Router 文档涵盖了您希望将视图嵌套在单个对象(例如/:people_id)中的情况。但是您想为一组对象嵌套视图。我想不出嵌套{{outlet}}视图的方法,但您可以执行以下操作:

在 3 个 ArrayController 中加载对象 People、Pets、Notes,并将对子对象的操作委托给其对应的 ArrayController。

App.Router = Ember.Router.extend({
  root: Ember.Route.extend({
    route: '/',
    persons: Ember.Route.extend({
        connectOutlets: function(router) {

          router.get('applicationController').connectOutlet('persons');
          // App.Note.find() fetches all Notes,
          // If you are not using ember-data, make sure the notes are loaded into notesController
          router.set('notesController.content', App.Note.find());
          router.set('petsController.content', App.Pet.find());
        }
    })
  })
});

然后您的people模板应如下所示:

{{#each person in people}}
  <h1>My name is {{person.name}}</h1>

  {{#each pet in person.pets}}
     I have a pet with name {{pet.name}}
     <a {{action delete pet target="App.router.petsController">Delete pet</a>
  {{/each}}      

  {{view Ember.TextField valueBinding="myNewPetName" type="text"}}
  <a {{action create myNewPetName person target="controller"}}>
    Add a new pet for this person
  </a>


  {{#each note in person.notes}}
    <!-- delete, create, edit ... -->
  {{/each}}

如您所见,子对象上的操作被委托给其控制器(pet -> petsController),将对象作为上下文传递。在create动作的情况下,控制器需要知道宠物对哪个人belongsTo。因此,我们传递了 2 个上下文:人和宠物的属性(为简单起见,我假设只是宠物的名字)。

在您的 App.petsControllers 中,您应该采取以下行动:

App.PetsController = Ember.ArrayController.extend({
   delete: function(e) {
     var context = e.context;
     this.get('content').removeObject(context);
     // Also, if you use ember-data,
     // App.Pet.deleteRecord(context);
   },

   create: function(e) {
     var petName = e.contexts[0]
     var person = e.contexts[1];
     this.get('content').pushObject({name: petName, person: person});
     // with ember-data:
     // App.Pet.createRecord({name: petName, person: person});
   }
});  
于 2012-10-04T22:35:05.907 回答
1

你应该使用插座。它们是 Ember 视图中的小“占位符”,可以使用不同的控制器进行处理。

上面的链接对它们有一个公平的解释,您已经检查过但什么也没找到。但在你回到之前,请先阅读: http: //trek.github.com/

如果其中任何一个仍然对您没有帮助,请告诉我,我会为您整理一个示例。

于 2012-09-29T08:44:40.190 回答
1

我认为就是您正在寻找的东西,请看一下,它非常简单,您也可以查看示例。基本上,您可以通过插座、路由器和连接所有插座的操作来实现您想要的。

于 2012-10-04T15:56:12.987 回答
0

我是 Ember 的新手,一直在寻找一种方法来做类似的事情。在顶级 ArrayController 中,我只使用了该itemController属性并且效果很好:

App.PeopleController = Ember.ArrayController.extend({
    itemController: "Person"
});

App.PersonController = Ember.ObjectController.extend //...

我的完整解决方案在这个 js fiddle中。不幸的是,我让PetController实例工作的方式对我来说似乎很老套。

于 2013-02-13T04:01:29.567 回答