ko.observable中的空数组

时间:2016-05-27 07:22:42

标签: javascript arrays knockout.js

我有一个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();

清空它们。这是可观察的问题吗?

2 个答案:

答案 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更新。

现在,如果您只使用booleannumber工作,那么您会注意到淘汰是否可以确定新值是否实际不同:



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;
&#13;
&#13;

但是对于对象,它的行为有所不同:

&#13;
&#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;
&#13;
&#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;一个数组:

  1. observableArray检查the relevant docs,因为他们有removeAll()实用程序方法。
  2. 要清空普通的javascript数组,请检查具有各种解决方案的this duplicate question,其中一个解决方案只是array.length = 0
  3. 最后请注意,如果您在视图模型中,可能需要首先执行self.filter()以获取observable中的对象。所以,例如:

    self.filter().file.length = 0; // plain array method
    

    但是,由于filesitestatut是纯数组(而不是observableArray),因此您的UI中不会自动更新。如果他们可观察数组,那么你可以:

    self.filter().file.removeAll(); // assuming `file` has been made observable