Javascript 如何重写主干集合移除方法,然后调用父级

Javascript 如何重写主干集合移除方法,然后调用父级,javascript,backbone.js,Javascript,Backbone.js,我正在遵循SO和其他网站的帖子中的建议,但无法实现这一点 我想覆盖所有主干集合上的remove函数,以便在删除所有模型后触发“removed”事件 我试过这个: …但它似乎以递归方式调用自身,并且从不激发父(基)remove方法 如何正确重写remove方法并调用base方法?重写原型,因此当调用它时,它将继续递归。 您要么需要创建一个新的基本集合来进行扩展,要么将该功能推送到现有的扩展中——这取决于您希望使其可重用的程度 var MyBaseCollection = Backbone.Coll

我正在遵循SO和其他网站的帖子中的建议,但无法实现这一点

我想覆盖所有主干集合上的remove函数,以便在删除所有模型后触发“removed”事件

我试过这个:

…但它似乎以递归方式调用自身,并且从不激发父(基)remove方法


如何正确重写remove方法并调用base方法?

重写原型,因此当调用它时,它将继续递归。 您要么需要创建一个新的基本集合来进行扩展,要么将该功能推送到现有的扩展中——这取决于您希望使其可重用的程度

var MyBaseCollection = Backbone.Collection.extend({
    remove: function(models, options){
        console.log('removing');
        Backbone.Collection.prototype.remove.call(this, models, options);
        this.trigger('removed', models);    
    }
});

var MyColl = MyBaseCollection.extend({ });

或者直接将其添加到MyColl中。

您正在覆盖主干收集原型上的
remove
,然后调用
remove
,因此它将调用自身

相反,您应该在实现中覆盖它:

var MyCollection = Backbone.Collection.extend({
  remove: function(models, options) {
    // Do your stuff
    // ..

    // Call the parent
    Backbone.Collection.prototype.remove.call(this, models, options)
  }
});
当然,您可以扩展
MyCollection
而不是
Backbone.Collection
以在其他控制器中继承此功能

您可以这样做:

var remove = Backbone.Collection.prototype.remove;
Backbone.Collection.prototype.remove = function(models, options){
    console.log('removing');
    remove.call(this, models, options);
    this.trigger('removed', models);    
};

我最喜欢的方法是使用下划线的
wrap()
,特别是因为默认情况下,下划线在主干中可用。我个人喜欢使用
wrap()
,因为它用通俗易懂的英语表达了正在发生的事情,比如:

Backbone.Collection.prototype.remove = _.wrap(
    Backbone.Collection.prototype.remove,
    function(original_remove, models, options) {
        // Capture original function arguments
        var original_args = Array.prototype.splice.call(arguments, 0, 1);

        // Before
        console.log('removing');

        // Call original function with original arguments
        original_remove.apply(this, original_args);

        // After
        this.trigger('removed', models);
    });
唯一需要注意的是
Array.prototype.splice
调用,它去掉了第一个参数(下划线设置为原始函数)。但是,这允许我们对原始参数使用
apply()
,这比
call()
灵活一点,因为它可以处理任意数量的参数,而不必显式命名它们


请注意使用
Array.prototype.splice
而不是
arguments.splice()
,这是必要的,因为
arguments
不是完整的Javascript数组类型,并且在其自己的原型中不携带splice方法。

工作起来很有魅力。谢谢
Backbone.Collection.prototype.remove = _.wrap(
    Backbone.Collection.prototype.remove,
    function(original_remove, models, options) {
        // Capture original function arguments
        var original_args = Array.prototype.splice.call(arguments, 0, 1);

        // Before
        console.log('removing');

        // Call original function with original arguments
        original_remove.apply(this, original_args);

        // After
        this.trigger('removed', models);
    });