我正在使用 Backbone.js 库执行以下操作:
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注解源代码,特别是以下代码:
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/
2条答案
按热度按时间mwngjboj1#
为了更好地理解Backbone.js代码,请给出详细的答案:
在JavaScript中,可以通过两种方式引用对象的“成员”:
1.常用的
.
符号:foo.say('hello');
[...]
表示法,以字符串为参数...有点像关联数组:foo["say"]('hello')
在Backbone.js中,
methods
数组中的每个字符串(在此方法上方定义)都被迭代并添加到Collection
原型中,因此它被添加到继承(或扩展)Collection
的所有类中。在函数中,
arguments
关键字只是引用传入函数的所有参数,即使签名为空:没有任何参数的切片将把传入的参数转换为数组。请注意这里使用了
slice.call(...)
(并参考this Stack Overflow question)。然后,
unshift
将Collection模型数组添加到数组的开头。然后我们实际上是在新的参数数组上调用Underscore方法(使用
[...]
表示法)。使用apply,我们传递_
作为第一个参数,它将成为this
作用域(更多信息是here)这允许您执行以下操作:
而不是
效果一模一样!前者只会叫后者。:)
为了回答你的问题,你的例子中的问题是
_.without
方法不接受两个数组,而是接受一个后面跟着一列参数的数组;你正在寻找的方法名为difference
(参见this SO question),但它没有Map到Collection中,所以你可以自己Map它(复制Backbone源代码中的代码),或者直接使用它:工作提琴:http://jsfiddle.net/tVmTM/177/
在我看来,最好继续使用
filter
,就像你对over_18
方法所做的那样。更好的是,将over_18
和under_18
作为方法放在Model中(它们所属的地方),然后从集合中使用它们。uxhixvfz2#
1)
methods
数组中的每个字符串对应于一个下划线方法,如_.forEach
,_.map
,_.reduce
等。对于methods
字符串,Collection
原型都会添加一个函数,该函数调用下划线方法,但将集合中的模型作为第一个参数传递,然后是您传入的任何选项。例如,假设您有一个名为
Dogs
的集合,其中包含一堆Dog
模型。调用Dogs.forEach(options)
将调用一个调用_.forEach(Dogs.models, options)
的函数。这是一个方便的事情。2)在第2行,你使用了
that
,而我认为你是指this
。在第3行,在without
之后有一个额外的.
。