2014-11-19 3 views
0

저는 일주일 동안 underscore.js를 사용 해왔고 정말 좋아합니다. 그러나 컬렉션 (vm.lists)의 단일 요소를 다른 요소로 대체하려고합니다.Underscore.js : 컬렉션의 항목 바꾸기

_.each(vm.lists, function (el) { 
    if (el.id == list.id) 
     el = list; 
}); 

과 :

var l = _.findWhere(vm.lists, { id: list.id }); 
l = list; 

그러나 그들 중 누구도 컬렉션에 실제 항목을 변경하지 나는 다음을 수행했습니다. 어떻게하면 제대로 할 수 있을까요?

답변

2

당신은 아주 가까이 있어요. 문제는 값을 가리키는 로컬 변수 (ell) 만 바꾸는 것이며 초기 목록을 수정하지 않는다는 것입니다. 더 간단한 예 : 개체

var list = [1, 2, 3]; 
var v = list[1]; 
v = 7; // v will now point to a new value, but list will stay intact [1, 2, 3] 

같은 :

가) 변화 vm.lists[index]는 그래서는 새로운 객체를 가리키는 :

var olist = [{id: 1, v: 2}, {id: 4, v: 6}]; 
var obj = olist[0]; 
obj = {id: 8, v: 10}; // changes what obj points to, but does not affect olist[0] 

var obj2 = olist[0]; 
obj2.v = 777; // olist[0] still points to the same object but the object is modified 

olist[0] = {id: 8, v: 10}; // changes what olist[0] points to 

그래서 기본적으로 두 가지 옵션이 있습니다. 목록에서 객체의 색인을 가져와 vm.lists[index] = newObject;을 수행해야합니다. 일부 언더 코어 조건자는 인덱스 _.each(list, function (el, index) {});을 제공합니다.

b) vm.lists[index]이 가리키는 개체를 변경하지만 수동으로 필드를 복사해야합니다. 개체가 {id: id, values: [1, 2, 3], anotherField: data}로 표시되는 경우 예를 들어, 필드를 복사 할 수 있습니다 :

//el.id = list.id; // don't need this as you were searching by id 
el.values = list.values; 
el.anotherField = list.anotherField; 

이 IMO 첫 번째 옵션은 깨끗한 것입니다.

+0

멋진 답변에 감사드립니다. – Rune

0

여기에 밑줄 필요가 없다 :

for (var i = 0, l = vm.lists.length; i < l; i++) 
{ 
    var el = vm.lists[i]; 
    if (el.id == list.id) { 
    vm.lists[i] = list; 
    break; // stop the for loop 
    } 
}