0

Backbone.jsに基づいて次の2つのビューがあります

pg.views.ItemList = Backbone.View.extend({

  tagName:  "div",
  className: "items",

  initialize: function() {
    _.bindAll(this, 'addOne', 'addSelected')

    Items.bind('add',     this.addOne);

    Items.fetch();
  },

  // REMOVED

  addOne: function(Item) {
    console.log($(this.el));
    var view = new pg.views.Item({model: Item});
    $(this.el).append(view.render().el);
  },

  addSelected: function(ItemList) {
    _.each(ItemList, this.addOne);
    return this.el;
  },

  // REMOVED

});

pg.views.Section = Backbone.View.extend({

  tagName:  "section",

  sectionTemplate: _.template($('#section-template').html()),

  events: {
    // REMOVED
  },

  initialize: function() {
    _.bindAll(this, 'render', 'close', 'addItemToSection', 'removeItemFromSection');
    this.model.bind('change', this.render);
    this.model.view = this;

    Items = new pg.collections.ItemList;
  },

  render: function() {
    $(this.el).html(this.sectionTemplate(this.model.toJSON()));
    this.setContent();
    Items.bind('add', this.addItemToSection);                   // "add" event bind
    Items.bind('remove', this.removeItemFromSection);           // "remove" event bind
    this.addItems();
    return this;
  },

  addItems: function() {
    var ids = this.model.get('items');
    var view = new pg.views.ItemList;
    var items = _.map(ids, function(id){ return Items.get(id); });
    $(this.el).append(view.addSelected(items));
  },

  // FUNCTIONS REMOVED

  setContent: function() {
    var title = this.model.get('title');
    this.$('.title').text(title);
    this.title = this.$('.title-input');
    this.title.val(title);
  },

  addItemToSection: function(Item) {
    console.log(this.model.get('title'));
    // REMOVED
  },

  removeItemFromSection: function(Item) {
    console.log(this.model.get('title'));
    // REMOVED
  }

});

これが私が直面している問題です。

ユーザーが2つのセクションを作成するビューがあります。たとえば、「section1」と「section2」という名前です。これらの名前は、「title」属性で使用されます。

これが私が観察している奇妙な行動です:

  1. ユーザーが「section1」にいてアイテムを追加すると、「add」バインドイベントがトリガーされ、その結果、「section2」がコンソールに書き込まれます。

  2. ユーザーが「section1」にいてアイテムを追加すると、「remove」バインドイベントがトリガーされ、その結果、「section1」がコンソールに書き込まれます。

  3. ユーザーが「section2」にいてアイテムを追加すると、「add」バインドイベントがトリガーされ、その結果、「section2」がコンソールに書き込まれます。

  4. ユーザーが「section2」にいてアイテムを追加すると、「remove」バインドイベントがトリガーされ、「section2」、次に「section1」がコンソールに書き込まれます。

「this.addItemToSection」を使用して「pg.views.Section」ビュー内に「add」をバインドしている場合、そのインスタンス内の「addItemToSection」ブロックのみを呼び出すべきではありませんか?

「this」を「再定義」しているのがわかるのは、「pg.views.ItemList」の初期化ブロックの「add」バインドだけです。その行が原因である場合、「section1」の「add」バインドで「this」が再定義されないようにするにはどうすればよいですか?

4

1 に答える 1

1

これはグローバルな問題だと思います。しゃれが意図されています;)Items最初にvarで宣言されたすべてのものを呼び出しています-(悪い習慣)は、ウィンドウオブジェクトにバインドされることを意味します。また、別のビューで同じ変数参照を使用します。したがって、両方が同じオブジェクトを参照しているため、両方が呼び出されます!!!! 'this'にバインドすることにより、必要な数の'local'インスタンスを持つことができます。次の変更を試してみてください。うまくいくはずです。

pg.views.ItemList = Backbone.View.extend({

  tagName:  "div",
  className: "items",

  initialize: function() {
    _.bindAll(this, 'addOne', 'addSelected')

    this.myItems = new pg.collections.ItemList(); //create local reference

    this.myItems.bind('add', this.addOne);

    this.myItems.fetch();
  },

  ...    
});

pg.views.Section = Backbone.View.extend({

  tagName:  "section",


  initialize: function() {
    _.bindAll(this, 'render', 'close', 'addItemToSection', 'removeItemFromSection');
    this.model.bind('change', this.render);
    this.model.view = this;

    this.mySectionItems = new pg.collections.ItemList; //add to 'this'
  },

  render: function() {
    $(this.el).html(this.sectionTemplate(this.model.toJSON()));
    this.setContent();
    this.mySectionItems.bind('add', this.addItemToSection);         // "add" event bind
    this.mySectionItems.bind('remove', this.removeItemFromSection); // "remove" event bind
    this.addItems();
    return this;
  },
...

});
于 2011-08-18T19:44:17.373 に答える