当我对可观察数组执行push或pop操作时,它会反映在ui中。然而,阵列上的其他操作不会改变UI中的任何内容。这里是我的情况的一个例子:KnockoutJS - UI不会使用内置的observableArray方法更新,除了push和pop
<ul data-bind="foreach: addresses">
<!-- ko template: {name: 'AddressItemTemplate', data: {address: $data, page: 'update-page'} }-->
<!-- /ko -->
</ul>
我用我的模板,在两个不同的页面和那我使用这样的模板数据的原因。
<script type="text/html" id="AddressItemTemplate">
<p data-bind="text: (page == 'update-page') ? 'updating' : 'declined'"</p>
<p data-bind="text: address.title"></p>
</script>
现在的JS侧,OFC我宣布地址作为可观察到的阵列
this.addresses = ko.observableArray([addresObject1, addressObject2, ...])
某处在页面上,我编辑的地址值。有UI反映了变化,我做了以下内容:
//suppose we know that the first address is being edited
var tmp_addresses = addresses();
tmp_addresses[0].title = 'blabla';
addresses(tmp_addresses);
它就在那里,在视图模型,我可以看到addresses
的内容已经更新,而不是在用户界面?
addresses.push(someAddressObject);
或
addresses.pop();
作品(更新与新的/除去元件的UI)。但addresses.splice(0, 1, newAddressObject)
不会再次在UI中执行任何操作。
我在这里错过了什么?如何推动流行工作,而不是其他人? 我是否遇到了淘汰赛框架中的错误?
UPDATE
我发现了一种方法来做到这一点,但这里有些不对劲。我会来,但首先:
我很清楚,如果我在observable数组中使用可观察对象,更改将反映在用户界面中。然而这正是我想要避免的事情。这是一个矫枉过正的问题。
在属性真正暴露给用户交互的情况下,应该要求可观察属性。例如,如果您有一个用于设置对象的每个字段的UI,那么是的,可观察属性将是正确的调用。
但在我的情况下,我甚至没有用于更新地址字段的UI。此外,我不需要修改,并不断观察所有地址的所有属性。在我的情况下,每隔一段时间从服务器进行一次更新,并且仅更改单个地址字段中的单个字段。
在另一个角度我建议的方式应该工作。我只是简单地更新整个数组,而不是每个元素都单独更新。这是完全一样的逻辑:
someObservableObject({newObject: withNewFields, ...});
这就是为什么我不需要我的对象作为observables。我只是想重新声明这个数组并且完成这个改变。例如,建议如果您要大量推入可观察数组,不要多次使用array.push(...),而是重新声明更大的数组到可观察数组变量我在我的问题中采用了类似的方式。否则,我告诉淘汰赛跟踪他们中的每一个单个对象和每一个领域,这不是我想要的。
现在,我终于得到它的工作但我的方式表明,有一个更干净的方式来做到这一点。
我发现,当您重新声明数组时,observable数组中的项目会以某种方式跟踪并且不会更新。例如,我在问题中给出的代码不起作用。然而,下面的代码工作:
var tmp_addresses = addresses();
var tmp_addr = tmp_addresses[0];
var new_addr = {};
Object.keys(tmp_addr).forEach(function(key){
new_addr[key] = tmp_addr[key];
});
new_addr.title = 'Hey this is something new!'
addresses.splice(0, 1, new_addr);
不满意?下面的代码是去工作为好,因为我们正在重新定义数组:
var newAddressObject1 = {...}, newAddressObject2 = {...};
addresses([newAddressObject1, newAddressObject2]);
但是下面是行不通的!
var tmp_addresses = addresses();
var tmp_addr = tmp_addresses[0];
tmp_addr.title = 'Hey this address wont update';
addresses.splice(0, 1, tmp_addr);
怎么回事?我认为knockout在observableArrays中添加了一个内部属性给他的项目,当我尝试重新插入它时,它不会更新。
我的问题现在已经演变为创建一个new
对象与可观察数组中的所需项目的相同属性。我上面编码的方式非常肮脏。有一个更好的方法可以做到这一点
我相信你的答案在这里:http://stackoverflow.com/questions/14953248/how-to-update-observable-array-element-in-knockoutjs – ryuu9187
数组是观察,而不是个别元素。 – ryuu9187
@ jason9187我没有更新单个元素,我正在更新整个数组。请查看我在 – batilc