我正在使用 EmberJS v1.0.pre 编写应用程序。我有一个 ArrayController
,其中包含所有人员的列表。有一堆嵌套 View 显示人、他们的宠物和每只宠物的注释。
|----------------------------------------|
| 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 的 Angular 来看,感觉每个 child 都应该有一个 Controller ,但我不知道如何在 Ember 中实现它。有最上面的 Array Controller ,然后是所有单独的 View 。如果我想删除或编辑笔记,似乎我需要将 View 的上下文传递给 Controller 。
// in the view
click: function () {
this.get('controller').updateNote(this.get('content'))
}
这让我感觉很糟糕,View 不应该是数据的权威来源。我的假设是 ArrayController 会实例化 itemControlerClass
以及 itemViewClass
。
更新:我创建了一个 fiddle更好地说明我的问题。功能有意不完整,目的是通过单击列表中的项目时增加内容来完成功能。
更新:抱歉,我不小心删除了 fiddle !我正在为最终解决方案做一些工作,所以我将尝试创建一个带有解决方案的新 fiddle 。
最佳答案
"From the pure MVC standpoint it feels like there should be a controller for each child"
您不需要为每个项目使用一个 Controller ,而是为每个对象集合(人、宠物、笔记)使用一个 ArrayController。顺便说一句,对子对象(狗、笔记)的任何操作都不应该传递给 App.PersonsController
。那会破坏 Separation of Concerns原则。
Ember.Router 文档涵盖了您想在单个对象中嵌套 View 的情况(例如 /:people_id
)。但是您想嵌套对象数组的 View 。我想不出嵌套 {{outlet}}
View 的方法,但您可以执行以下操作:
在3个ArrayController中加载People、Pets、Notes对象,并将子对象的 Action 委托(delegate)给对应的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}}
如您所见,对子对象的操作委托(delegate)给它的 Controller (pet -> petsController),将对象作为上下文传递。在 create
操作的情况下, Controller 需要知道宠物 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});
}
});
关于javascript - EmberJS 嵌套 View 和 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12602429/