当使用不同的参数多次触发相同的事件时,Backbone.Marionette Scope问题

时间:2012-08-15 23:15:07

标签: javascript-events backbone.js triggers scope marionette

情况

我正在尝试使用模型和集合来呈现嵌套数据结构的概述。 特别是,我正在加载SubjectsCollection,其中每个主题都有一些属性,其中一个应该是嵌套的LessonsCollection

我的控制器加载SubjectsCollection。 加载SubjectsCollection后,控制器会使用SubjectListView呈现Marionette.CollectionView(a SubjectsCollection)并显示在Marionette.Region中。

SubjectModel中的每个SubjectListView都会呈现为SubjectLayoutMarionette.Layout)。

SubjectListView中显示Marionette.Region后,一个函数会循环显示SubjectLayout并触发package-definition:subject:layout:ready上的事件(App.vent)(每Marionette.EventAggregatorSubjectLayout),将SubjectLayout作为参数传递给任何要接收的回调。

期望的效果

名为openLessons的方法会对package-definition:subject:layout:ready事件作出反应并加载LessonsCollection。这应该多次发生(每次渲染SubjectLayout一次。)

每个LessonsCollection应该呈现LessonsListView,而LessonsListView应该显示在他们所属的SubjectLayout的{​​{1}}区域中。< / p>

SubjectsCollection实例应该作为参数传递给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收到SubjectLayout

此外,每个LessonsListView的'课程'属性都包含最后加载的SubjectsCollection

显然这里有一个范围问题。

问题

问题是:

  1. 为什么所有LessonsCollection都会使用上一个SubjectsCollection覆盖他们的'课程'属性?
  2. 为什么只有最后一个LessonsCollection实例才会收到SubjectLayout
  3. 如何解决问题?

1 个答案:

答案 0 :(得分:0)

解决

嗯,这有点令人尴尬。事实证明问题一直是我在全球范围内意外定义了一些变量,例如:

var that = this,
  subject = subjectLayout.model; // <-- should've been a comma... *headdesk*
  subject_id = subject.get('id'),
  lessons = subject.get('lessons') || new LessonsCollection(),
  lessonsRegion = subjectLayout.lessons;