情况
我试图渲染模型和集合嵌套数据结构的概况触发相同的事件时Backbone.Marionette范围问题。 特别是,我正在加载一个SubjectsCollection
,其中每个主题都有一些属性,其中一个属性应该是嵌套的LessonsCollection
。多次使用不同的参数
我的控制器加载了SubjectsCollection
。 加载SubjectsCollection
后,控制器将呈现SubjectListView
(a Marionette.CollectionView
)与SubjectsCollection
并显示在Marionette.Region
中。
SubjectListView
中的每个SubjectModel
都被渲染为SubjectLayout
(a Marionette.Layout
)。
一旦SubjectListView
显示在Marionette.Region
,通过SubjectLayout
的一个函数的周期,并触发对每个SubjectLayout
上App.vent
一个事件(package-definition:subject:layout:ready
)(一个Marionette.EventAggregator
),传递SubjectLayout
作为参数用于任何回调来接收。
所需的效果
的方法称为openLessons
反作用于package-definition:subject:layout:ready
事件并加载LessonsCollection
。这应该发生多次(每次渲染SubjectLayout
一次)。
每个LessonsCollection
应该呈现LessonsListView
和LessonsListView
应的区域中显示在与它们所属的SubjectsCollection
的SubjectLayout
。
SubjectLayout
的实例假定作为参数向openLessons
方法来传递,所以每个LessonsListView
可以在它的相应SubjectLayout
的所分配的区域中显示。
守则
这里是到目前为止,我已经得到了代码:
var PackageDefinition_Overview_Controller = Controller.extend({
...
Data: {
packageDefinition: {
// attributes: {
// foo: 'bar',
// subjects: [{
// attributes: {
// baz: 'quux',
// lessons: []
// }
// }]
// }
}
},
// Initialization
//---------------
initialize: function() {
...
this.bindTo(App.vent, "package-definition:subject:layout:ready", this.openLessons);
},
...
openSubjects: function(packageDefinitionOverviewLayout) {
var that = this,
packageDefinition = packageDefinitionOverviewLayout.model;
packageDefinition_id = packageDefinition.get('id'),
subjects = packageDefinition.get('subjects') || new SubjectsCollection(),
subjectsRegion = packageDefinitionOverviewLayout.subjects;
...
subjects.load(packageDefinition_id);
...
subjects.isLoaded.done(function() {
packageDefinition.set({
subjects: subjects
});
that.showSubjectListView(subjectsRegion, subjects);
});
...
},
openLessons: function(subjectLayout) {
var that = this,
subject = subjectLayout.model;
subject_id = subject.get('id'),
lessons = subject.get('lessons') || new LessonsCollection(),
lessonsRegion = subjectLayout.lessons;
...
lessons.load(subject_id);
...
lessons.isLoaded.done(function() {
console.log('Data', that.Data);
subject.set({
lessons: lessons
});
that.showLessonsListView(lessonsRegion, lessons);
});
...
},
...
showSubjectListView: function(region, subjects) {
var subjectsListView = new SubjectsListView(subjects);
region.show(subjectsListView);
// Time to load the Lessons
subjectsLayouts = subjectsListView.children;
_.each(subjectsLayouts, function(subjectLayout) {
App.vent.trigger("package-definition:subject:layout:ready", subjectLayout);
}, this);
},
showLessonsListView: function(region, lessons) {
var lessonsListView = new LessonsListView(lessons);
region.show(lessonsListView);
}
});
问题
尽管事实上,package-definition:subject:layout:ready
被多次触发,以及多个LessonsCollection
的get加载。只有最后的SubjectLayout
收到它的LessonsListView
。
而且,每个SubjectsCollection
的'课程'属性包含最后加载的LessonsCollection
。
所以很明显,这里有一个范围问题。
的问题
的问题是:
- 为什么所有
SubjectsCollection
得到他们的 '教训' 属性与上次LessonsCollection
覆盖? - 为什么只有最后一个
SubjectLayout
实例收到LessonsListView
? - 如何解决问题?