我有一个self.filter({ file: [], site: [], statut: [] })`
,其对象包含3个这样的数组:
array = []
当我尝试清空它时,它不起作用。我试过了
//For simplicity , assume they are in same file.
function Caller ()
{
dalmethod(function(err,db){
do some thing
// I am done here
});
}
function dalmethod(callback)
{
// Connect database & call this function
callback(somevalue,db);
//after call back function is executed call some more methods. such as closing the db.
// db.close();
}
Caller();
清空它们。这是可观察的问题吗?
答案 0 :(得分:2)
您不需要观察所有可观察对象的数组以便能够更新UI,尽管我当然(像其他回答者一样)建议您这样做。
我想解释为什么它不起作用。
假设您有以下代码:
var originalObject = {
myArray: [1, 2, 3]
};
var myObservable = ko.observable(originalObject);
// Resetting the array behind knockout's back:
originalObject.myArray = [1, 2, 3, 4];
最后一行更改了用于设置 observable的对象的属性。淘汰赛没有办法知道你已经更新了你的对象。如果你想让淘汰赛重新考虑可观察的谷歌,你必须告诉它一些改变了:
myObservable.valueHasMutated();
现在,通常,您通过将新的或更新的变量传递给它来更新observable,如下所示:
myObservable(newValue);
奇怪的是,再次使用同一个对象设置observable也有效:
myObservable(originalObject);
这就是原因:
在内部,knockout将newValue
与它当前持有的值进行比较。如果值相同,则不会执行任何操作。如果它们不同,则会设置新值并执行必要的UI更新。
现在,如果您只使用boolean
或number
工作,那么您会注意到淘汰是否可以确定新值是否实际不同:
var simpleObservable = ko.observable(true);
simpleObservable.subscribe(function(newValue) {
console.log("Observable changed to: " + newValue);
});
simpleObservable(true); // Doesn't log
simpleObservable(false); // Does log

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
&#13;
但是对于对象,它的行为有所不同:
var myObject = { a: 1 };
var simpleObservable = ko.observable(myObject);
simpleObservable.subscribe(function(newValue) {
console.log("Observable changed to: " + JSON.stringify(newValue, null, 2));
});
simpleObservable(myObject); // Does log, although nothing changed
simpleObservable({b: 2 }); // Does log
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
&#13;
即使我们使用了完全相同的对象来重置我们的可观察对象,也会触发订阅!如果你挖掘淘汰赛的源代码,你就会明白为什么。它使用此方法检查新值是否不同:
var primitiveTypes = { 'undefined':1, 'boolean':1, 'number':1, 'string':1 };
function valuesArePrimitiveAndEqual(a, b) {
var oldValueIsPrimitive = (a === null) || (typeof(a) in primitiveTypes);
return oldValueIsPrimitive ? (a === b) : false;
}
简单地说:如果旧值不是原始值,它只会假设事情发生了变化。这意味着只要我们重置了observable,我们就可以更新originalObject
。
originalObject.myArray.length = 0;
myObservable(originalObject);
或者,同样简单:
myObservable(Object.assign(originalObject, { myArray: [] });
有点长的答案,但我相信很高兴知道为什么的东西不起作用,而不是仅仅绕过它。即使只是简单地使用observableArray
并让淘汰优化其工作也是更好的解决方案!
答案 1 :(得分:1)
你提及&#34; 清空&#34;数组。请注意,这与&#34; 将新的空数组分配给变量&#34;不同。无论如何,如果你想&#34;清空&#34;一个数组:
observableArray
检查the relevant docs,因为他们有removeAll()
实用程序方法。array.length = 0
。最后请注意,如果您在视图模型中,可能需要首先执行self.filter()
以获取observable中的对象。所以,例如:
self.filter().file.length = 0; // plain array method
但是,由于file
,site
和statut
是纯数组(而不是observableArray
),因此您的UI中不会自动更新。如果他们是可观察数组,那么你可以:
self.filter().file.removeAll(); // assuming `file` has been made observable