我正在寻找一种高效的方法来根据参考数组中记录ID的存在来更新集合中的选定记录。例如,给定[1,2,5]的引用数组,我希望集合中的每个记录都具有$selected: true
的属性。集合中的每条记录都会与视图中的复选框相关联,并会检查$selected
项目(fiddle)
我从下面的方法(coffeescript)开始,但我是Lodash的新手,所以我想我会要求一些反馈。另外,我不确定将$selected: false
设置为备用记录的最简洁方法是什么?
# Whole Collection
collection = [
{id:1, name: "one"},
{id:2, name: "two"},
{id:3, name: "three"},
{id:4, name: "four"},
{id:5, name: "five"}
]
# Mark subset as selected
for id in [1,2,5]
_.where( collection, 'id':id ).forEach( (record) ->
record.$selected = true
)
这是一个小提琴...... http://jsfiddle.net/zd78e4bj/
修改 添加了对视图
中复选框的双向绑定$selected
元素的引用
答案 0 :(得分:0)
我会做这样的事情(抱歉,它不是CoffeScript,但你明白了):
var collection = [
{ id:1, name: 'one' },
{ id:2, name: 'two' },
{ id:3, name: 'three' },
{ id:4, name: 'four' },
{ id:5, name: 'five'}
];
var ids = [ 1, 2, 5 ];
_(collection)
.indexBy('id')
.at(ids)
.each(_.ary(_.partialRight(_.assign, { $selected: true }), 1))
.value();
console.log(collection);
// →
// [
// { id: 1, name: 'one', $selected: true },
// { id: 2, name: 'two', $selected: true },
// { id: 3, name: 'three' },
// { id: 4, name: 'four' },
// { id: 5, name: 'five', $selected: true }
// ]
首先,我们使用indexBy()创建一个中间对象。密钥是id
中的collection
值。接下来,我们会通过at()我们感兴趣的ID。这会构建一个新的集合,其中只包含我们之后的ID。
最后一步是使用each()添加$selected
属性。这是通过合并partialRight(),assign()和ary()来完成的。部分应用的参数是新的$selected
属性。我们使用ary()
来确保传递给each()
的回调只有一个参数。
答案 1 :(得分:0)
您可以使用map
或forEach
功能在Lodash或本机JavaScript中执行所有操作。 Map
创建一个新列表,forEach
将改变现有列表。
这些的关键是转换功能。如果在{ids集合中存在或不存在,则此函数将$selected
设置为true或false。
function mark(item) {
item['$selected'] = (ids.indexOf(item.id) > -1);
return item;
}
您可以使用以下方法构建更通用的转换器:
function markItemByList(list, property, searchField) {
return function(item) {
item[property] = (list.indexOf(item[searchField]) > -1);
return item;
}
}
Coffeescript将是:
markItemByList = (list, property, searchField) ->
(item) ->
item[property] = (list.indexOf(item[searchField])) > -1)
item
如果你想要一个可变的实现:
function select(ids, collection) {
collection.forEach(markItemByList(ids, '$selected', 'id'));
}
这是一个lodash不可变的实现:
function select(ids, collection) {
return _.map(collection, markItemByList(ids, '$selected', 'id'));
}
这是一个纯JavaScript不可变的实现:
function select(ids, collection) {
return collection.map(markItemByList(ids, '$selected', 'id'));
}
这是一个角度实现:
angular.forEach(collection, markItemsByList(ids, '$selected', 'id'));