2012-11-05 41 views
22

基本上我有一個observableArray併爲每個項目中的值不是一個可觀察的。這意味着,當我改變的項目值的observableArray的foreach循環內的用戶界面不會相應地更新。刷新observableArray當項目不可觀測量

這意味着一個巨大的變化,如果我有將它們設置爲可觀察到的,那麼有沒有一種方法,我可以刷新無論是UI或手動observableArray的foreach?

回答

46

是的,你可以調用valueHasMutated功能爲您的數組:

yourArray.valueHasMutated(); 

編輯: 如果第一次沒幫助,你可以做 '髒' 刷新:

self.refresh = function(){ 
    var data = self.array().slice(0); 
    self.array([]); 
    self.array(data); 
}; 

這裏是工作提琴:http://jsfiddle.net/vyshniakov/FuEy6/2/

+5

這仍然不會更新我的用戶界面 – user1166905

+1

valueHasMutated適合我。 – Edyn

+7

爲什麼你需要通過調用slice(0)來複制數組?下面的工作,以及甚至更好'var data = self.array(); self.array(null); self.array(data);' –

5

我最終使用從上面的髒的方法,但說得那麼我所有的可觀測陣列有這個功能。

ko.observableArray.fn.refresh = function() { 
     var data = this().slice(0); 
     this([]); 
     this(data); 
    }; 

valueHasMutated對我無效。它的一種跛腳的整個列表中已被更新。或者在我的情況下找到一種方法來擴展ko映射插件,以便用可觀察對象填充可觀察陣列。

+2

'var data = this()/ *。slice()* /; this(null); this(data);'會運行得更好,更快 –

16

當您有一個帶有非可觀察元素的可觀察數組,並且數組中某個元素的某些屬性發生更改如果你想只刷新該元素,你可以使用indexOfsplice,像這樣:

var changedIdx = obsArray.indexOf(changedItem); 
obsArray.splice(changedIdx , 1); // removes the item from the array 
obsArray.splice(changedIdx , 0, changedItem); // adds it back 

這個做什麼,正在尋找數組中的元素,刪除它,並將其插入回來。當它插回,元素再次被束縛,用新值。然後

ko.observableArray.fn.refresh = function (item) { 
    var index = this['indexOf'](item); 
    if (index >= 0) { 
     this.splice(index, 1); 
     this.splice(index, 0, item); 
    } 
} 

,當你改變一個數組的項目,您只需撥打這個電話:

如果你喜歡這個解決方案,可以延長所有KO觀察到陣列的功能,如下所示:

obsArray.refresh(changedItem); 

如果你有你的數組中的很多元素,你會得到改善服務表現關於dirty刷新由阿爾喬姆Vyshniakov,其更新綁定在陣列中的所有元素,而不是隻爲一個改變。

注:valueHasMutated,被無證(以及在內部使用,我想)APPART,只檢查,如果數組本身發生了變化,而不是如果陣列中的不可觀察的元件已改變,所以它不」將不起作用。即如果已經添加元素添加到數組其僅檢測,從數組移除的元件,改變所述陣列的元素與新的,不同的元件,或者改變了的元素的順序。但它不檢查元件本身已經改變

+0

美麗,有用的東西,謝謝 – Andrew

+0

請注意'obsArray.indexOf ''使用'==='查找匹配值的元素,但在javascript中{'x':'X'} === {'x':'X'}'return false –

+0

你是對的。但是,在這種情況下**你有一個你想mofidy **的數組元素的引用。你不會修改一個看起來像數組中的對象,而是數組中的對象。所以,使用'indexOf'會發現它。如果更改了不在數組中的對象,則必須用新數組替換數組中的對象,這與更改數組**中某個元素的屬性不同,並通知它已更改,另一種情況完全不同。 – JotaBe

0

我發現了一個簡單的解決方案通過更換陣列中的整個對象。

在本例中參數IX是索引,oLine是更新的對象和oVM.objProps。行包含數組。解決方案像冠軍一樣工作。

/* This contortion causes the computed function to fire because 
* we have replaced the entire line object. 
*/ 
function forceRefresh(ix,oLine) { 
    var oVM = pme.getVM(); 
    oLine = JSON.parse(JSON.stringify(oLine)); 
    oVM.oObjProp.lines[ix] = oLine; 
}