【问题标题】:Backbone Collection Add Event Firing Once骨干集合添加事件触发一次
【发布时间】:2012-09-23 17:54:13
【问题描述】:

我有一个 Backbone 集合,当我向其中添加一个新模型时,“add”事件似乎没有像我预期的那样工作。我已经绑定了 2 个视图来监听集合上的添加事件,但似乎只有一个视图收到了事件通知,并且当这种情况发生时,没有 PUT 请求发送到我的服务器。当我删除第二个绑定时,另一个工作并发送 PUT 请求。这是代码sn-ps:

    var FlagList = Backbone.Collection.extend({
    model: Flag  // model not shown here... let me know if it would help to see
});

    var FlagCollectionView = Backbone.View.extend({
    el: $('ul.#flags'),
    initialize: function() {
        flags.bind('add', this.addFlag, this);  // this one doesn't fire!!
    },
    addFlag: function(flag) {
        alert("got it 1");  // I never see this popup
    }
});

    var AddFlagView = Backbone.View.extend({
    el: $("#addFlagPopup"),
    events: {
        "click #addFlag": "addFlag"
    },
            initialize: function() {
                    flags.bind('add', this.closePopup, this);   // this one fires!!
            }
    addFlag: function() {
        flags.create(new Flag);
    },
    closePopup: function() {
        alert("got it 2");  // I see this popup
    }
});

var flags = new FlagList;
var addFlagView = new AddFlagView;
var flagCollectionView = new FlagCollectionView;

【问题讨论】:

  • 这是实际的执行顺序吗?即:在初始化 flagCollectionView 之前是否发送了来自“单击#addFlag”的事件?在您期望事件触发之前将事件绑定到模型和集合,这一点很重要

标签: backbone.js backbone-events


【解决方案1】:

一些建议:

ID 与类

你已经通过结合一个类和一个 id 来过度限定你的选择器。 jQuery 允许这样做,但是 ID 选择器在页面上应该是唯一的,所以将 el: $('ul.#flags') 更改为 el: $('ul#flags')

利用骨干

我喜欢将我的集合和/或模型显式传递给我的视图,并在视图上使用神奇的 collectionmodel 属性。

var flags = new FlagList;
var addFlagView = new AddFlagView({collection: flags});
var flagCollectionView = new FlagCollectionView({collection: flags});

这意味着在您看来,您将自动访问 this.collection

解除绑定事件以避免重影视图

var FlagCollectionView = Backbone.View.extend(
{
    initialize: function (options)
    {
        this.collection.bind('add', this.addFlag, this);
    },
    addFlag: function (flag)
    {
        alert("got it 1");
    },
    destroyMethod: function()
    {
        // you need some logic to call this function, this is not a default Backbone implementation
        this.collection.unbind('add', this.addFlag);
    }
});

var AddFlagView = Backbone.View.extend(
{
    initialize: function ()
    {
        this.collection.bind('add', this.closePopup, this);
    },
    closePopup: function ()
    {
        alert("got it 2");
    },
    destroyMethod: function()
    {
        // you need some logic to call this function, this is not a default Backbone implementation
        this.collection.unbind('add', this.closePopup);
    }
});

看来我必须同意@fguillen,您的问题一定出在您初始化视图的方式上,正如我在评论中提到的那样,它很可能与时间有关,即:将您的事件绑定到集合之后'add' 事件已经触发。

【讨论】:

  • 很好的解释,我之前在用类似于 ghost views 的东西打架:stackoverflow.com/questions/10429648/…
  • 非常有帮助。我做了你建议的改变。谢谢!顺便说一句,关于 id 的,ul#flags 不也是这样吗?如果 id 'flags' 在页面上是唯一的(它是),我想我需要的只是 el: $('#flags')... 对吗?
【解决方案2】:

此代码适用于我:

var FlagList = Backbone.Collection.extend({});

var FlagCollectionView = Backbone.View.extend({
  initialize: function() {
    flags.bind('add', this.addFlag, this); 
  },
  addFlag: function(flag) {
      alert("got it 1");
  }
});

var AddFlagView = Backbone.View.extend({
  initialize: function() {
    flags.bind('add', this.closePopup, this);
  },
  closePopup: function() {
    alert("got it 2");
  }
});

var flags = new FlagList;
var addFlagView = new AddFlagView;
var flagCollectionView = new FlagCollectionView;

flags.add({key:"value"});

check the jsFiddle

您的问题出在其他地方。

【讨论】:

  • 你是对的。我的代码中其他地方的异常导致脚本执行停止。感谢您让我步入正轨!
【解决方案3】:

如果你在犯了我犯的同样愚蠢的错误后来到这里,请确保你有:

this.collection.bind( 'add', this.render )

this.collection.bind( 'add', this.render() )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    相关资源
    最近更新 更多