简答
使用_.invoke 而不是_.pluck
见this sample fiddle。
长答案
_.pluck(list, propertyName) 按文档说明工作:
可能是最常见的 map 用例的便捷版本:提取属性值列表。
或者,正如 lodash 文档中更好的解释:_.pluck(collection, path)
从集合中的所有元素中获取path的属性值。
所以,如果你这样做:
_.pluck(myArray(), "id")
你得到的是一个包含所有id 的数组。所有这些id 都是可观察的,就像在原始数组的对象中一样
但您可以使用_.invoke(list, methodName, *arguments),如文档所述:
对列表中的每个值调用由 methodName 命名的方法。传递给调用的任何额外参数都将转发给方法调用。
或者,在lodash版本_.invoke(collection, path, [args])
在集合中每个元素的路径上调用方法,返回每个调用方法的结果数组。为每个调用的方法提供任何附加参数。如果 methodName 是一个函数,它会被调用,并且 this 绑定到集合中的每个元素。
这样,你执行每个 observable,并按预期获取它的值:
_.invoke(myArray(), "id")
注意充满可观察对象的视图模型!
对这个问题的第一条评论让我包含了这个通知:
最好的解决方案是使用ko.toJS 将视图模型中的所有可观察对象转换为具有常规属性的常规 JavaScript 对象。完成后,下划线或任何其他库将按预期工作。
_.invoke 解决方案仅适用于单层可观察对象,如本例所示。如果有多层嵌套的 observables,它将完全失败,因为它在路径的末尾调用一个函数,而不是在路径的每一步,例如,_.invoke 不适用于这种情况:
var advices = [{
person: ko.observable({
name = ko.observable('John')
}),
advice: ko.observable('Beware of the observables!')
}];
在这种情况下,您只能在第一级使用_.invoke,如下所示:
var sentences = _.invoke(advices,'advice');
但这行不通:
var names = _.invoke(advices,'person.name');
在这个调用中,只会调用name,但不会调用person,所以这会失败,因为person 是一个可观察对象,因此它没有name 属性。
注意:lodash 是另一个类似的库,主要兼容下划线,但在某些方面更好