使用where方法的Backbone / Underscore链方法

时间:2012-10-26 16:37:55

标签: backbone.js underscore.js lodash

这里必须有一些简单的东西。

http://jsfiddle.net/v9mdZ/

我正在学习Backbone和Underscore / loDash,我正在尝试熟悉chain

我有以下代码,它按预期工作:

var ids = _.pluck(collection.where({'is_checked':true}), 'id');

我尝试使用chain进行重构,如下所示:

var ids = collection.chain().where({'is_checked':true}).pluck('id').value();

为什么重构代码不起作用?我使用chain错了吗?

解决方案(详情如下)

请勿将wherechain一起使用。

1 个答案:

答案 0 :(得分:18)

some Underscore methods合并到集合中有点不完美。当你说collection.some_mixed_in_underscore_method()时,该集合会展开你背后的一些Backbone内容,以便将Underscore方法应用于集合模型中的属性;它有点像这样:

var ary = _(this.models).map(function(m) { return m.attributes });
return _(ary).some_mixed_in_underscore_method();

但是collection.chain()不起作用,chain只是直接包装集合的models,所以如果你这样做:

console.log(collection.chain());

你会看到chain给你一个包装模型数组的对象。您的模型不会有is_checked属性(即没有model.is_checked),但它们会有is_checked个属性(即model.get('is_checked')和{{1} })。

现在我们可以看到出现问题的地方:

model.attributes.is_checked

模型没有collection.chain().where({'is_checked':true}) 属性。特别是,is_checkedis_checked并且true之后的所有内容都使用空数组时,不存在任何模型。

现在我们知道事情的发展方向,我们如何解决这个问题?好吧,您可以使用filter代替where,以便轻松解压模型:

where

但是,您的模型还没有collection.chain() .filter(function(m) { return m.get('is_checked') }) .pluck('id') .value(); ,因为您没有使用id创建它们而您还没有与服务器通信以获得id你将获得一系列id的回复。如果您添加一些undefined s:

id

然后你会得到你正在寻找的var collection = new App.OptionCollection([ {id: 1, 'is_checked': true}, {id: 2, 'is_checked': true}, {id: 3, 'is_checked': false} ]);

演示:http://jsfiddle.net/ambiguous/kRmaD/