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