2013-08-05 32 views
3

我一直在尋找documentation淘汰賽的observableArray,我無法弄清楚如何做一個數組最基本的事情:按索引分配一個值。通過索引爲knockout.js observableArray指定元素的正確方法是什麼?

事情我已經試過:(給出oa = ko.observableArray([1,2,3])

  • oa(1, 10);
  • oa[1] = 10;
  • oa()[1] = 10;
  • oa.splice(1, 1, 10);

最後一個似乎工作,但我很擔心那.splice()可能是我因爲它必須關注所有後續值的移動。我寧願只做簡單的基於索引的分配。

我已經created a jsfiddle顯示observableArray是奇怪的。

<ol data-bind="foreach: list"> 
    <li data-bind="text: $data"></li> 
</ol> 

<script> 
    var model = { 
     list: ko.observableArray([3, 5, 7]) 
    }; 

    ko.applyBindings(model); 

    setTimeout(function() { 
     model.list()[1] = 55; 
     model.list.push(99); 
     model.list()[2] = 77; 
    }, 2000); 
</script> 

回答

5

修改

setTimeout(function() { 
    model.list()[1] = 55; 
    model.list.push(99); 
    model.list()[2] = 77; 
    model.list.valueHasMutated(); 
}, 2000); 
1

你在你的小提琴中賦值的方式工作正常。如果您執行model.list()對象的console.log(),則實際上可以看到數組的值已正確更新。

要記住的是在文檔中的以下位最關鍵的事情:

關鍵點:一個observableArray軌道哪些對象數組中,這些對象

的不是國家乾脆把一個對象成可觀察數組並不能使所有對象的屬性都可以被觀察到。當然,如果你願意,你可以讓這些屬性可觀察,但這是一個獨立的選擇。 observableArray只追蹤它保存的對象,並在添加或刪除對象時通知偵聽器。

這就是您的視圖沒有被索引2中的新值更新的原因,因爲它不是可觀察的值。東西(快速和骯髒的)類似這樣的將工作:

var model = { 
    list: ko.observableArray([ko.observable(3), ko.observable(5), ko.observable(7)]) 
}; 
model.list()[2](77); // Yeah, looks weird. 
+1

「的observableArray軌道哪些對象數組中,這些對象不在狀態」後,適用於你的觀察到valueHasMutated財產。這就是爲什麼我期望有一些機制可以用另一個對象替換數組中的對象,並且ko會意識到這一點。我的例子不顯示我改變數組中的對象的屬性,而是替換整個對象。儘管如此,這是一個重要的想法,你是對的。 – recursive

3

可觀察陣列通知其偵聽的變化(並因此使相應的視圖更新)突變方法被調用或它與一個新的數組初始化時。

oa()[i] = x; 
oa(oa()); 

您可以考慮此因素伸到一個擴展方法:

ko.observableArray.fn.setItem = function(index, newValue) { 
    var items = this(); 
    items[index] = newValue; 
    this(items); 
}; 

foreach結合是足夠聰明,發現只有一個元素被改變,沒有必要再次進行渲染其他節點。

相關問題