2013-02-03 3 views
0

사용자가 검색을 수행 할 수있는 개체 배열이 있습니다. 검색을 기반으로 ko.computed 함수를 사용하여 표시 할 일치 항목의 다른 배열을 만듭니다.knockout.js 두 개의 배열을 만드는 함수를 계산 했습니까?

self.matchedRecords = ko.computed(function() { 
    return ko.utils.arrayFilter(self.transponders(), function(r) { 
    return r.title.toLowerCase().indexOf($('.search-input').val().toLowerCase()) > -1 
    } 
}; 

위대한 작품이며 지금까지의 성능에 깊은 인상을 받았습니다.

이 문제는 일부 경우 (60 %의 시간)에 추가 작업을 수행해야하므로 "불일치"레코드가 필요합니다. 두 번째 ko.computed 함수를 생성하고 싶지는 않습니다. 검색을 수행 할 때마다이 배열을 두 번 실행해야하기 때문입니다.

제 질문 : 동일한 ko.computed를 사용하여 일치하지 않는 항목의 두 번째 배열을 만들 수있는 방법이 있습니까? 기본적으로 배열을 실행하고 일치하거나 일치하지 않는 배열에 각 항목을 넣으십시오.

그렇지 않은 경우 다음을 수행하는 것이 더 빠릅니다. 1) 두 번째 ko.computed를 만들어 내 배열에서 일치하지 않는 항목을 사용자로 가져옵니다. 검색; 또는 2) arrayDiff 함수를 작성하고 필요에 따라 불일치 항목을 결정하십시오.

건배!

+0

그냥 계산 된 2를 사용하면 조기 최적화 –

답변

1

성능에 대해 걱정할 경우 계산 결과에서 반복되는 검색 결과를 반복하는 동안 볼 수없는 배열을 가질 수 있습니다. 또한 루프 내에서 반복적으로 jQuery를 사용하여 선택한다는 점에 유의하십시오. 이는 KO로 인한 속도 저하를 무효화한다고 생각합니다.

self.missedRecords = []; 

self.matchedRecords = ko.computed(function() { 
    var searchQuery = $('.search-input').val().toLowerCase(), 
     transponders = self.transponders(), 
     matched = []; 

    // Clear out missed records 
    self.missedRecords.length = 0; 

    _.each(transponders, function(transponder) { 
     if (transponder.title.toLowerCase().indexOf(searchQuery) >= 0) { 
      matched.push(transponder); 
     } else { 
      self.missedRecords.push(transponder); 
     } 
    }); 

    return matched; 
}); 

나는 코드가 짧게 유지하기 위해 밑줄에서 _.each을 사용했다. 이 방법의 단점은 missedRecords에 대한 변경 사항이 UI에 바운드 될 수 없다는 점입니다 (예 : foreach 바인딩 인 경우). 당신이 일 빠른 (어)를 유지하려면 여전히 관찰, 그리고 할 수 missedRecords 배열을 필요로 할 경우

, 당신이 뭔가를 할 수 있습니다 :

self.missedRecords = ko.observableArray([]); 

self.matchedRecords = ko.computed(function() { 
    var searchQuery = $('.search-input').val().toLowerCase(), 
     transponders = self.transponders(), 
     matched = [], 
     missed = []; 

    _.each(transponders, function(transponder) { 
     if (transponder.title.toLowerCase().indexOf(searchQuery) >= 0) { 
      matched.push(transponder); 
     } else { 
      missed.push(transponder); 
     } 
    }); 

    // Clear out missed records, without triggering subscriptions 
    self.missedRecords().length = 0; 

    // Copy the local missed array to the KO observable array 
    // This will NOT trigger notifications 
    ko.utils.arrayPushAll(self.missedRecords(), missed); 

    // Tell KO that the observable array has mutated - this will trigger changes 
    // to anything observing the missedRecords array 
    self.missedRecords.valueHasMutated(); 

    return matched; 
}); 

또한 모두 computed를 건너 뛸 수 있고 단지에 가입 배열의 상태가 변경됩니다. 예를 들어 : - 감사

self.missedRecords = ko.observableArray([]); 
self.matchedRecords = ko.observableArray([]); 

self.transponders.subscribe(function(newTransponders) { 
    var matched = [], 
     missed = []; 

    _.each(newTransponders, function(transponder) { 
     // Populate matched/missed local arrays 
    }); 

    // Copy the arrays to the observableArray instances using the technique above 
}); 
+0

에 떨어지고 난 그런 식으로 일을 생각하지 않습니다 .. 당신이 구독 그것을 생각! – whiteatom