gpt4 book ai didi

javascript - 混合每个 Underscore 方法作为 Collection#models 的代理

转载 作者:搜寻专家 更新时间:2023-11-01 04:25:28 24 4
gpt4 key购买 nike

我正在使用主干库执行以下操作:

var Persons = Backbone.Collection.extend({
defaults: {
name: 'unknown',
age: 18
},

over_18: function () {
return this.filter(function (model) {
return model.get('age') > 18
});
},

under_18: function () {

var persons_over_18 = this.over_18;

return this.without(this, persons_over_18); // it does not work!! why?
}
});

persons = new Persons([{age: 17}, {age: 27}, {age:31} ]);

persons.under_18().length; // 3 instead of 1

如您所见,under_18 方法无法正常工作,因为它返回了所有模型而不是只给我年龄属性低于 18 岁的模型。

所以为了调试我的代码,我决定查看 Backbone.js Annotated Source ,特别是以下代码:

var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl', ... ]; // and more

_.each(methods, function(method) {
Collection.prototype[method] = function() {
var args = slice.call(arguments);
args.unshift(this.models);
return _[method].apply(_, args);
};
});

但是上面这段代码我不是很清楚,我仍然无法让第一个代码如我所愿。

所以我的问题是如何修复与第二个代码相关的第一个代码?

这是我在 jsfiddle.net 中的代码 http://jsfiddle.net/tVmTM/176/

最佳答案

为了更好地理解 Backbone 代码的冗长回答:

在 javascript 中,可以通过两种方式引用对象的“成员”:

  1. 通常的 . 表示法:foo.say('hello');
  2. [...] 表示法,以字符串作为参数...有点像关联数组:foo["say"]('你好')

backbone 中发生的事情是 methods 数组中的每个字符串,就在这个方法之上定义,被迭代并添加到 Collection 原型(prototype)中,因此添加到所有类中继承(或扩展)Collection

在函数中,arguments 关键字简单地引用传递给函数的所有参数,即使签名为空也是如此:

Collection.prototype[method] = function() { // <- empty signature here!

没有参数的切片会将传递的参数转换为数组。注意此处使用了 slice.call(...)(并引用 this SO question)。

var args = slice.call(arguments);

unshift 然后将集合模型数组添加到数组的开头。

args.unshift(this.models);

然后我们实际上在新的参数数组上调用 Underscore 方法(使用 [...] 表示法)。使用 apply,我们将 _ 作为第一个参数传递给 this 作用域(更多信息 here)

return _[method].apply(_, args);

这允许您执行以下操作:

MyCollection.each(function (model) { ... });

代替

_.each(MyCollection.models, function (model) { ... });

产生的效果相同!前者只会调用后者。 :)

要回答你的问题,你的问题是 _.without 方法不接受两个数组,而是一个数组后跟一个参数列表;您正在寻找的方法称为 difference (查看 this SO question ),但它未映射到集合中,因此您可以自己映射它(复制在 Backbone 源中找到的代码)或直接使用即可:

return _.difference(this.models, this.over_18());

工作 fiddle :http://jsfiddle.net/tVmTM/177/

在我看来,最好继续使用 filter,就像您对 over_18 方法所做的那样...更好的是,将 over_18under_18 作为模型中的方法(它们所属的地方)和集合中的方法只使用它们。

关于javascript - 混合每个 Underscore 方法作为 Collection#models 的代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21165516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com