2013-06-12 110 views
0

我正在嘗試解決淘汰賽的問題。我想要做的是有一個根模型,包含另一個模型的observableArray。該模型還包含最後一個模型的一個observableArray(稱爲「結果」)。 根據用戶交互,可以完全更改第一個observableArray(重置數組並添加其他模型)。Knockout - 更新模型的observableArray

一個列表呈現給用戶,他能夠用文本字段過濾結果(我正在使用計算過濾器)。

我面臨的問題是,即使我重置了observableArray,似乎引用保留在嵌套模型中,並且敲除繼續在這些模型上觸發事件,從而導致將更多的Javascript調用作爲用戶更改列表。

我已經寫了一個小的jsfiddle來說明我的意思:http://jsfiddle.net/PNzM5/ 下面是javascript代碼:

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> 

我登錄到計算的呼叫到控制檯。如果你點擊「第一個列表」並嘗試過濾結果,你會看到對於你鍵入的每個字符,計算結果將被調用每個列表(這很好)。然後,如果你點擊「第二個列表」並嘗試過濾agin,你會看到計算機會被調用4次。每次點擊一個按鈕時,你還有2個電話。

(我真正的模型要複雜得多。例如,結果含有更多的屬性)

什麼我與我的真實模型是IE8告訴我,一個腳本正在放緩IE。我懷疑這是原因。即使不是,我想知道爲什麼我會得到這種行爲。也許這更像是一個JavaScript問題而不是Knockout問題?或者,也許我做錯了方式?

回答

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);   
    } 
} 

我也減少了我真正的「結果」模式可觀的數量(我有很多觀測和他們中的一些不需要被觀察到。簡單的屬性就夠了。我沒有得到IE錯誤對話框了。 但是,我認爲我的解決方案有點怪異。如果有人有更好的解決方案,我會很高興看到它。 :)

編輯:我忘了的jsfiddle:http://jsfiddle.net/PNzM5/2/

相關問題