14

我必须在这里缺少一些简单的东西。

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.

4

1 回答 1

18

一些 Underscore 方法合并到集合中有点不完美。当你说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')and model.attributes.is_checked)。

现在我们可以看到哪里出了问题:

collection.chain().where({'is_checked':true})

模型没有is_checked属性。特别是,不会有任何模型 where is_checkedistrue以及之后的所有内容都在where使用空数组。

既然我们知道事情的发展方向,我们该如何解决呢?好吧,您可以使用filter而不是where这样您就可以轻松地解压模型:

collection.chain()
          .filter(function(m) { return m.get('is_checked') })
          .pluck('id')
          .value();

但是,您的模型还没有ids,因为您没有使用ids 创建它们,并且您还没有与服务器交谈以获取ids,因此您将得到一个undefineds 数组。如果添加一些ids:

var collection = new App.OptionCollection([
    {id: 1, 'is_checked': true},
    {id: 2, 'is_checked': true},
    {id: 3, 'is_checked': false}
]);

然后你会得到[1,2]你正在寻找的。

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

于 2012-10-26T18:09:45.943 回答