0

我有以下两个基于 Backbone.js 的视图

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
  }

});

这是我遇到的问题。

我有一个用户创建两个部分的视图,假设它们被称为“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 声明的所有内容-(不好的做法)意味着它将绑定到 window 对象。您在另一个视图中使用相同的变量引用!所以两者都会被调用,因为它们引用了同一个对象!!!!通过绑定到“this”,您可以拥有任意数量的“本地”实例。尝试以下更改,我想它们应该可以工作。

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 回答