1

状況

モデルとコレクションを使用して、ネストされたデータ構造の概要をレンダリングしようとしています。SubjectsCollection特に、各サブジェクトにはいくつかの属性があり、そのうちの 1 つはネストされた であると想定されている をロードしていLessonsCollectionます。

私のコントローラーはSubjectsCollection. がSubjectsCollection読み込まれると、コントローラーはSubjectListView(a Marionette.CollectionView) をレンダリングし、 aSubjectsCollectionに表示されMarionette.Regionます。

SubjectModel内のそれぞれが(a )SubjectListViewとしてレンダリングされます。SubjectLayoutMarionette.Layout

SubjectListViewに表示されるMarionette.Regionと、関数は を循環し、それぞれの (a ) でSubjectLayoutイベント ( package-definition:subject:layout:ready)をトリガーし、受信するコールバックの引数としてを渡します。App.ventMarionette.EventAggregatorSubjectLayoutSubjectLayout

望む効果

呼び出されたメソッドがイベントにopenLessons反応し、 . これは複数回発生する必要があります (レンダリングされたものごとに 1 回)。package-definition:subject:layout:readyLessonsCollectionSubjectLayout

それぞれLessonsCollectionが をレンダリングし、が属するの領域に表示LessonsListViewする必要があります。LessonsListViewSubjectLayoutSubjectsCollection

インスタンスは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'lessons' 属性には、最後LessonsCollectionに読み込まれたものが含まれます。

したがって、明らかにスコープの問題がここにあります。

質問

質問は次のとおりです。

  1. SubjectsCollectionすべての「レッスン」属性が最後の で上書きされるのはなぜ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 に答える