这里必须有一些简单的东西。
我正在学习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
错了吗?
解决方案(详情如下)
请勿将where
与chain
一起使用。
答案 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_checked
为is_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}
]);
。