2013-06-12 2 views
0

녹아웃 문제를 해결하려고합니다. 내가 뭘하려는 것은 다른 모델의 observableArray를 포함하는 루트 모델을 갖는 것입니다. 이 모델에는 하나의 마지막 모델 ("결과"라고 함)의 observableArray도 포함됩니다. 사용자 상호 작용에 따라 첫 번째 observableArray가 완전히 변경 될 수 있습니다 (배열을 재설정하고 다른 모델 추가).녹아웃 - 모델의 observableArray 업데이트

목록이 사용자에게 렌더링되고 텍스트 필드를 사용하여 결과를 필터링 할 수 있습니다 (필터를 사용하여 계산 됨).

내가 직면하는 문제는 observableArray를 다시 설정하더라도 참조가 중첩 된 모델에 유지되고 녹아웃이 이러한 모델에서 이벤트를 계속 실행하여 점점 더 많은 자바 호출을 발생시키는 것입니다. 사용자가 목록을 변경합니다.

ko.observableArray.fn.pushAll = function (valuesToPush) { 
    var underlyingArray = this(); 
    this.valueWillMutate(); 
    ko.utils.arrayPushAll(underlyingArray, valuesToPush); 
    this.valueHasMutated(); 
    return this; 
}; 

function Result(value) { 
    this.value = ko.observable(value); 
} 

function NestedItem(name, currentValue) { 
    var _this = this; 
    this.currentValue = currentValue; 
    this.name = ko.observable(name); 
    this.totalResults = ko.observableArray([]); 
    this.filteredResults = ko.computed(function() { 
     console.log('get called by ' + _this.name()); 
     return ko.utils.arrayFilter(_this.totalResults(), function (result) { 
      return result.value().toLowerCase().indexOf(_this.currentValue()) != -1; 
     }); 
    }); 
} 

function Model() { 
    var _this = this; 
    this.nestedItemList = ko.observableArray([]); 
    this.currentValue = ko.observable(""); 

    this.createFirstList = function() { 
     this.nestedItemList([]); 
     _this.createItem("sublist 1", [new Result("value 1"), new Result("value 2"), new Result("value 3")]); 
     _this.createItem("sublist 2", [new Result("value 4"), new Result("value 5"), new Result("value 6")]); 
    } 

    this.createSecondList = function() { 
     this.nestedItemList([]); 
     _this.createItem("sublist 3", [new Result("value 1"), new Result("value 2"), new Result("value 3")]); 
     _this.createItem("sublist 4", [new Result("value 4"), new Result("value 5"), new Result("value 6")]); 
    } 

    this.createItem = function (name, values) { 
     var item = new NestedItem(name, _this.currentValue); 
     item.totalResults.pushAll(values); 
     this.nestedItemList.push(item); 
    } 
} 

및 관련 HTML :

<input data-bind="value:currentValue,valueUpdate: 'keyup'" type="text" placeholder="Type to filter"/> 
<ul data-bind="foreach: nestedItemList"> 
    <li class="sublist" data-bind="text: name"></li> 
    <!-- ko foreach: filteredResults --> 
    <li class="result" data-bind="text: value"></li> 
    <!-- /ko --> 
</ul> 
<button data-bind="event: {click: createFirstList}">First list</button> 
<button data-bind="event: {click: createSecondList}">Second list</button> 

내가 계산에 대한 호출을 기록 http://jsfiddle.net/PNzM5/ 여기 는 자바 스크립트 코드 :

내가 무슨 뜻인지 보여주기 위해 작은 jsfiddle을 작성했습니다 콘솔에. "첫 번째 목록"을 클릭하고 결과를 필터링하려고하면 입력 한 각 문자에 대해 각 목록에 대한 계산이 호출된다는 것을 알 수 있습니다 (괜찮습니다). 그런 다음 "두 번째 목록"을 클릭하고 agin을 필터링하려고하면 계산 된 값이 4 번 호출됩니다. 그리고 버튼을 누를 때마다 2 번 더 전화를 겁니다.

는 (내 실제 모델은 훨씬 더 복잡합니다. 예를 들어, 결과는 훨씬 더 많은 속성이 포함되어 있습니다) 내가 내 진짜 모델로 얻을 것은 IE8은 스크립트가 IE를 아래로 둔화되고 있음을 말해입니다

. 그리고 이것이 이것이 이유라고 생각합니다. 그렇지 않은 경우에도 왜 이러한 행동을 취하고 있는지 알고 싶습니다. 어쩌면 그것은 녹아웃 문제보다 자바 스크립트 문제일까요? 아니면 내가 잘못하고있는 것일까 요?

답변

0

좋아, 해결책을 찾았습니다. 는 "NestedItem"에서, 나는 하늘의 배열에 결과를 설정하는 리셋 기능을 생성 :

this.reset = function() { 
    _this.totalResults([]); 
} 

그리고 나는 또한 새로운 목록이 생성 될 때마다 호출되는 루트 모델의 리셋 기능을 작성 :

this.reset = function() { 
    ko.utils.arrayForEach(_this.nestedItemList(), function(list) { 
     list.reset(); 
    }); 
    this.nestedItemList([]); 
} 

그래서, 모델은 지금 :

ko.observableArray.fn.pushAll = function(valuesToPush) { 
    var underlyingArray = this(); 
    this.valueWillMutate(); 
    ko.utils.arrayPushAll(underlyingArray, valuesToPush); 
    this.valueHasMutated(); 
    return this; 
}; 

function Result(value) { 
    this.value = ko.observable(value); 
} 

function NestedItem(name, currentValue) { 
    var _this = this; 
    this.currentValue = currentValue; 
    this.name = ko.observable(name); 
    this.totalResults = ko.observableArray([]); 
    this.filteredResults = ko.computed(function() { 
     console.log('get called by ' + _this.name()); 
     return ko.utils.arrayFilter(_this.totalResults(), function(result) { 
      return result.value().toLowerCase().indexOf(_this.currentValue()) != -1 ; 
     }); 
    }); 
    this.reset = function() { 
     _this.totalResults([]); 
    } 
} 

function Model() { 
    var _this = this; 
    this.nestedItemList = ko.observableArray([]); 
    this.currentValue = ko.observable(""); 

    this.createFirstList = function() { 
     _this.reset(); 
     _this.createItem("sublist 1 title", [new Result("value 1"), new Result("value 2"), new Result("value 3")]); 
     _this.createItem("sublist 2 title", [new Result("value 4"), new Result("value 5"), new Result("value 6")]); 
    } 

    this.createSecondList = function() { 
     _this.reset(); 
     _this.createItem("sublist 3 title", [new Result("value 1"), new Result("value 2"), new Result("value 3")]); 
     _this.createItem("sublist 4 title", [new Result("value 4"), new Result("value 5"), new Result("value 6")]); 
    } 

    this.reset = function() { 
     ko.utils.arrayForEach(_this.nestedItemList(), function(list) { 
      list.reset(); 
     }); 
     this.nestedItemList([]); 
    } 

    this.createItem = function(name, values) { 
     var item = new NestedItem(name, _this.currentValue); 
     item.totalResults.pushAll(values); 
     this.nestedItemList.push(item);   
    } 
} 

나는 또한 나의 진짜 "결과"모델에서 관찰 가능한의 수를 감소 (I는 관찰 가능한 많이했고, 그들 중 일부 관찰 할 필요가 없었다. 간단한 속성으로 충분했습니다. 더 이상 IE 오류 대화 상자가 표시되지 않습니다. 하지만 여전히 내 솔루션은 약간 해키라고 생각합니다. 누구든지 더 좋은 해결책을 가지고 있다면, 나는 그것을 보게되어 기쁠 것이다. :)

편집는 : http://jsfiddle.net/PNzM5/2/

: 나는 jsfiddle를 잊어 버렸습니다