我一直在关注淘汰赛的documentation 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显示一个可观察的阵列很奇怪。
<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>
答案 0 :(得分:5)
修改后在您的observable上应用 valueHasMutated 属性
setTimeout(function() {
model.list()[1] = 55;
model.list.push(99);
model.list()[2] = 77;
model.list.valueHasMutated();
}, 2000);
答案 1 :(得分:3)
当调用mutating方法或使用新数组初始化时,Observable数组会通知其侦听器更改(从而导致相应的视图更新)。
oa()[i] = x;
oa(oa());
您可以将其分解为扩展方法:
ko.observableArray.fn.setItem = function(index, newValue) {
var items = this();
items[index] = newValue;
this(items);
};
foreach
绑定非常智能,可以检测到只有一个元素被更改,并且不需要再次呈现其他节点。
答案 2 :(得分:1)
你在小提琴中分配价值的方式很好。如果您执行了model.list()对象的console.log()
,则实际上可以看到数组的值已正确更新。
要记住的关键是文档中的以下内容:
关键点:observableArray跟踪数组中的对象,而不是那些对象的状态
简单地将对象放入observableArray并不会使该对象的所有属性本身都可观察到。当然,如果您愿意,您可以观察这些属性,但这是一个独立的选择。 observableArray只跟踪它所拥有的对象,并在添加或删除对象时通知侦听器。
这是您的视图未使用索引2中的新值更新的原因,因为它不是可观察的值。像这样的东西(快速和肮脏)将起作用:
var model = {
list: ko.observableArray([ko.observable(3), ko.observable(5), ko.observable(7)])
};
model.list()[2](77); // Yeah, looks weird.