1

情况

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

我的控制器加载SubjectsCollection. 一旦SubjectsCollection加载了 ,控制器就会渲染一个SubjectListView(a Marionette.CollectionView),SubjectsCollection并显示在 a 中Marionette.Region

中的每个SubjectModelSubjectListView呈现为SubjectLayout(a Marionette.Layout)。

一旦SubjectListView显示在 中Marionette.Region,函数就会循环遍历并在(a ) 上为每个SubjectLayout触发一个事件 ( ) ,将作为参数传递给要接收的任何回调。package-definition:subject:layout:readyApp.ventMarionette.EventAggregatorSubjectLayoutSubjectLayout

想要的效果

一个被调用的方法openLessons对事件做出反应package-definition:subject:layout:ready并加载一个LessonsCollection. 这应该发生多次(每次SubjectLayout渲染一次)。

每个都LessonsCollection应该呈现一个LessonsListView,并且LessonsListView应该显示在它们所属SubjectLayout的区域中。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被触发多次,并且 multipleLessonsCollection被加载。只有最后一个SubjectLayout收到它的LessonsListView.

此外,每个SubjectsCollection“课程”属性都包含最后LessonsCollection加载的内容。

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

问题

问题是:

  1. 为什么所有人SubjectsCollection都会用 last 覆盖他们的“课程”属性LessonsCollection
  2. 为什么只有最后一个SubjectLayout实例收到一个LessonsListView
  3. 我该如何解决问题?
4

1 回答 1

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;
于 2012-08-16T12:04:07.493 回答