2012-08-15 89 views
1

情况

我试图渲染模型和集合嵌套数据结构的概况触发相同的事件时Backbone.Marionette范围问题。 特别是,我正在加载一个SubjectsCollection,其中每个主题都有一些属性,其中一个属性应该是嵌套的LessonsCollection多次使用不同的参数

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

SubjectListView中的每个SubjectModel都被渲染为SubjectLayout(a Marionette.Layout)。

一旦SubjectListView显示在Marionette.Region,通过SubjectLayout的一个函数的周期,并触发对每个SubjectLayoutApp.vent一个事件(package-definition:subject:layout:ready)(一个Marionette.EventAggregator),传递SubjectLayout作为参数用于任何回调来接收。

所需的效果

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

每个LessonsCollection应该呈现LessonsListViewLessonsListView应的区域中显示在与它们所属的SubjectsCollectionSubjectLayout

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

所以很明显,这里有一个范围问题。

的问题

的问题是:

  1. 为什么所有SubjectsCollection得到他们的 '教训' 属性与上次LessonsCollection覆盖?
  2. 为什么只有最后一个SubjectLayout实例收到LessonsListView
  3. 如何解决问题?

回答

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; 
相关问题