2013-07-19 4 views
2

백본이 Collection이며 자체 업데이트 (추가, 제거, 재설정)에 응답하려고합니다. 나는 다양한 시나리오에서이로 실행되지만이를 살펴보기 위해, 내가 빨리 컬렉션을 비교, 모델 ID를 기반으로 해시를 계산하고있어 가정 해 봅시다했습니다추가/제거/재설정시 백본 컬렉션 속성 업데이트

var HashedCollection = Backbone.Collection.extend({ 
    updateHash: function() { 
     // set a simple hash based on model id 
     this.hash = this.pluck('id').sort().join('|'); 
    } 
}); 

질문은, 권리 무엇을 내 해시를 최신 상태로 유지하는 방법?

가능한 옵션 : 이벤트에 대한

  • 설정 자체 청취자 :

    this.on('add remove reset', this.updateHash, this); 
    

    이의 문제가 일부 작업은 침묵 할 수 있다는 것입니다,하지만 난 여전히 해시를 업데이트 할 - 특히 초기 모델에서는이 문제가 발생합니다. initialize에는 컬렉션이 아직 모델이없고 초기 재설정 이벤트가 무음이므로 (relevant code) 발생할 수 없습니다. 또한 다른 구성 요소가 { silent: true }을 전달하여 컬렉션 상태를 엉망으로 만들 수 있음을 의미합니다.

  • 설정 기능을 오버라이드 (override) .add, .remove, .reset 및/또는 .set에 대한 :

    set: function() { 
        Backbone.Collection.prototype.set.apply(this, arguments); 
        this.updateHash(); 
    } 
    // etc 
    

    여기서 가장 큰 문제는 하나의 add/set 호출 대 reset에서 여러 통화를 처리하는 - reset 전화 add 여러 번 이는 set을 여러 번 호출하므로 set을 래핑하면 재설정시 항목 당 한 번 해시가 업데이트됩니다. updateHash이 위의 간단한 예제보다 비싸다면 이는 실제 문제 일 수 있습니다. 다른 작은 문제는 내가 오버라이드 된 함수로 끝나기 때문에 더 많은 세미 - 상용구 코드와 코어 메소드의 버그 가능성이 더 커진다는 것입니다.

설명의 편의를 위해 a) 해시 계산이 비싸고 b) 해시가 자주 참조됩니다.

모델을 최신 상태로 유지하기위한 더 나은 접근 방법이 있습니까?

+0

하고 무엇을 끝낼 않았다 - 여기

set:function() { Backbone.Collection.prototype.set.apply(this,arguments); this.updateHash(); }, 

데모를위한 바이올린입니까? – fbynite

+0

내 자신의 코드에서, 나는 현재 여전히 초기 'reset' 이벤트에 대한 수정과 함께 자체 청취자를 사용하고 있습니다. 하지만 아마도 아래의 답 중 하나를 올바른 것으로 표시해야합니다. 왜냐하면 두 가지가 모두 현재의 방식보다 낫다고 생각하기 때문입니다 ... – nrabinowitz

답변

1

내가 틀릴 수도 있지만 "가장 큰 문제"(귀하의 단어)는 문제가 아닌 것 같습니다.

resetadd입니다.

// from backbone source - Backbone.Collection.reset 
reset: 
... code above ... 
this.add(models, _.extend({silent: true}, options)); // note - silent:true 
... code below ... 

add

한 번 set를 호출합니다.

// from backbone source - Backbone.Collection.add 
add: function(models, options) { 
    return this.set(models, _.defaults(options || {}, addOptions)); 
}, 

(당신이 보여준대로) 당신이 set 오버라이드 (override)하는 경우 updateHash은 리셋 한 번 호출됩니다. http://jsfiddle.net/5ggCd/

또한 오버라이드 (override) 할 필요가 remove

remove:function() { 
    Backbone.Collection.prototype.remove.apply(this,arguments); 
    this.updateHash(); 
}, 
+0

그건 ... 아주 좋은 지적입니다. 따라서 메서드 대체 옵션이 훨씬 매력적입니다. – nrabinowitz

1

구체적인 정보는 제공하지 않으므로보다 자세한 답변을하기는 어렵지만 일반적으로는 뒤로하고 있습니다. 당신이 실제로 그것을 필요로 할 때까지 당신 대신 당신이 그것을 필요로 할 때 언제든지 당신이 this.getHash()를 호출해야 this.hash에 참조하는,

getHash : function(){ 
    return this.pluck('id').sort().join('|'); 
} 

을 해시를 업데이트해야합니다. 그러면 모든 동기화 문제가 사라집니다.

변경 사항을 적용한 다음 작업을 수행하려는 경우 컬렉션 이벤트를 수신하지만 컬렉션에서 수신 대기해야하는 상황이 있음을 알리는 내용은 없습니다.

+0

좋은 점은 있지만, a) 해시를 계산하는 데 많은 비용이 들며 b) 해시는 자주 참조됩니다. 해시 온 디맨드 방식은이 경우 훨씬 효율적이지 않으며 업데이트시에만 컴퓨팅합니다. – nrabinowitz

+0

당신의 접근 방식이 맞을지 모르지만 IFF의 .getHash 함수는 해시를 현재 ID 목록으로 계산할 때 ID 목록을 비교하고 필요한 경우에만 비싼 부분을 수행했습니다. 잘 최선의 선택일지도 모릅니다. – nrabinowitz