JavaScript – EmberJS嵌套视图和控件

我正在用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'))
}

这对我来说真的很糟糕,View不应该是数据的权威来源.我的假设是ArrayController将与itemViewClass一起实例化一个itemControlerClass.

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

更新:抱歉,我意外删除了小提琴!我正在做一些最终解决方案的工作,所以我会尝试创建一个新的解决方案.

解决方法

“From the pure MVC standpoint it feels like there should be a controller for each child”

您不需要每个项目的控制器,而是每个对象集合(People,Pets,Notes)的ArrayController.顺便说一下,对于对象(狗,笔记)的任何操作都不应该被传递给App.PersonsController.这将打破Separation of Concerns原则.

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

在3 ArrayController中加载对象People,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());
        }
    })
  })
});

然后你的人员模板应该是:

{{#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),将对象作为上下文传递.在创建动作的情况下,控制器需要知道宠物属于哪个人.因此,我们通过了两个环境:人和宠物的属性(为了简单起见,我只假定宠物的名字).

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

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});
   }
});

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...