Ответ 1
"С чистой точки зрения MVC кажется, что для каждого ребенка должен быть контроллер"
Вам не нужен контроллер для каждого элемента, но вместо этого ArrayController для каждой коллекции объектов (People, Pets, Notes). Кстати, любые действия над дочерними объектами (собаки, заметки) не должны передаваться на App.PersonsController
. Это нарушит принцип Разделение проблем..
Документы Ember.Router охватывают случай, когда вы хотите вложить представления в один объект (например, /:people_id
). Но вы хотите вложить представления для массива объектов. Я не могу придумать способ вложенных представлений {{outlet}}
, но вы можете сделать следующее:
Загрузите объекты People, Pets, Notes в 3 ArrayControllers и делегируйте действия дочерним объектам в соответствующий 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
. Поэтому мы передаем два контекста: человек и свойства домашнего животного (для простоты я принял только имя для домашнего животного).
В вашем 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});
}
});