Sproutcore nested array one to many binding
I have three tiers of objects, each as one to many. I'd like, when a different notebook is selected, that the page and column view elements get cascading updates.
Notebook > Pages > Columns
With notebooksController and notebookController I can bind
App.Notebook = SC.Record.extend({
name: SC.Record.attr(String),
pages: SC.Record.toMany('App.Page', {isMaster: YES, inverse: 'notebook'})
});
App.Page = SC.Record.extend({
pageNumber: SC.Record.attr(Number),
notebook: SC.Record.toOne('App.Notebook', {isMaster: NO, inverse: 'pages'}),
columns: SC.Record.toMany('App.Column', {isMaster: YES, inverse: 'page'})
});
App.Column = SC.Record.extend({
columnNumber: SC.Record.attr(Number),
page: SC.record.toOne('App.Page', {isMaster: NO, inverse: 'columns'})
});
Following this, I can't seem to get the content binding for pagesController to work. I want the contents of pagesController, pageController, columnsController, and columnController to be cascaded down so that when a user clicks a different notebook, the views presented automatically flick across to the correct content.
ArrayController notebooksController
// contents filled from fixture
ObjectController notebookController
// bound to notebooksController selection
ArrayController pagesController
// contentBinding: 'notebookController.pages' does not work!
ObjectController pageController
// bound to pagesController selection
//开发者_Python百科 and down to column
Assuming you have a single Notebook, try
App.notebookController = SC.ObjectController.create({
// call App.notebookController.set('content', aNotebook)
// to set the content on this controller
});
App.pageController = SC.ArrayController.create({
// the notebookController is a proxy to the its content, so you dont need
// 'content' in the binding contentBinding: 'App.notebookController.pages'
// bind the list view to App.pagesController.arrangedObjects. If you look in the code
// arranged objects is a reference to the array controller itself, which has array methods
// on it
});
App.pageSelectionController = SC.ObjectController.create({
// You need to add
//
// selectionBinding: 'App.pageSelectionController.content
//
// to the collection view where you select the page
// you can do this in places to see when things change. This controller is just a proxy
// to the selected page.
selectionDidChange: function(){
console.log('page selection changed to [%@]'.fmt(this.get('content');
}.observes('content')
});
App.columnsController = SC.ArrayController.create({
contentBinding: 'App.pageSelectionController.columns'
// again, where you want to show the columns, bind to
// App.columnsController.arrangedObjects
});
I found the answer. Turns out you can indeed simply use App.notebookController.pages.
The problem was, my fixtures were not set up correctly. It is not enough to map the child to the parent, the parent has to be mapped back to the child.
I originally had:
Autofocus.Notebook.FIXTURES = [
{ guid: 1, title: "Home Notebook", columnCount: 2},
{ guid: 2, title: "Work Notebook", columnCount: 2}
];
And was all fixed when I did the following:
Autofocus.Notebook.FIXTURES = [
{ guid: 1, title: "Home Notebook", columnCount: 2, pages: [11, 12] },
{ guid: 2, title: "Work Notebook", columnCount: 2, pages: [21, 22]}
];
精彩评论