订阅新的或删除条目可观测阵列只(Subscribe to observable array for

2019-07-17 19:59发布

所以,是的,我可以订阅可观察到的数组:

vm.myArray = ko.observableArray();
vm.myArray.subscribe(function(newVal){...});

问题是newVal传递给函数是整个阵列。 反正我只能得到增量部分? 说的添加删除元素?

Answer 1:

作为KnockoutJS 3.0,有一个arrayChange订阅选项上ko.observableArray。

var myArray = ko.observableArray(["Alpha", "Beta", "Gamma"]);

myArray.subscribe(function(changes) {

    // For this example, we'll just print out the change info
    console.log(changes);

}, null, "arrayChange");

myArray.push("newitem!");

另外,在上述的回调,所述变化参数将是这样的变化的对象的数组:

[ 
   { 
      index: 3, 
      status: 'added', 
      value: 'newitem!' 
   }
]

为了您的具体问题, 你想被通知的新的或删除的项目 。 要实现,使用淘汰赛3,它会是这样的:

myArray.subscribe(function(changes) {

    changes.forEach(function(change) {
        if (change.status === 'added' || change.status === 'deleted') {
            console.log("Added or removed! The added/removed element is:", change.value);
        }
    });

}, null, "arrayChange");


Answer 2:

因为我无法找到这个其他地方的任何信息,我会增加对如何与打字稿用这个答复。

这里的关键是使用KnockoutArrayChange接口TEvent的订阅。 如果你不这样做,它会尝试使用其他(非通用)订阅和会抱怨状态,索引和值不存在。

class ZoneDefinition {
    Name: KnockoutObservable<String>;
}

class DefinitionContainer
{
    ZoneDefinitions: KnockoutObservableArray<ZoneDefinition>;
    constructor(zoneDefinitions?: ZoneDefinition[]){
        this.ZoneDefinitions = ko.observableArray(zoneDefinitions);
        // you'll get an error if you don't use the generic version of subscribe
        // and you need to use the KnockoutArrayChange<T> interface as T
        this.ZoneDefinitions.subscribe<KnockoutArrayChange<ZoneDefinition>[]>(function (changes) {
            changes.forEach(function (change) {
                if (change.status === 'added') {
                    // do something with the added value
                    // can use change.value to get the added item
                    // or change.index to get the index of where it was added
                } else if (change.status === 'deleted') {
                    // do something with the deleted value
                    // can use change.value to get the deleted item
                    // or change.index to get the index of where it was before deletion
                }
            });
        }, null, "arrayChange");
}


Answer 3:

为了只检测push()remove()事件,而不是移动项目,我把围绕这些观察到的阵列功能的包装。

var trackPush = function(array) {
    var push = array.push;
    return function() {
        console.log(arguments[0]);
        push.apply(this,arguments);
    }
}
var list = ko.observableArray();
list.push = trackPush(list);

原来的推送功能存储在一个封闭,然后上覆盖的包装,让我不要做任何事情之前,我想用推的项目,或之后,将其推到阵列上。

类似模式remove()



Answer 4:

我使用的是类似的,但不同的方法,跟踪是否一个元素在元素本身被装备:

myArray.subscribe(function(array){
  $.each(array, function(id, el) {
    if (!el.instrumented) {
      el.instrumented = true;
      el.displayName = ko.computed(function(){
        var fn = $.trim(el.firstName()), ln = $.trim(el.lastName());
        if (fn || ln) {
          return fn ? (fn + (ln ? " " + ln : "")) : ln;
        } else {
          return el.email();
        }
      })
    }
  });
})

但它确实是繁琐和在我的代码的模式重复



Answer 5:

没有,我知道的。 想知道我做什么? 我使用一个变量来保存的价值,一种叫selectedItem

vm.selectedItem = ko.observable({});
function addToArray(item) { vm.selectedItem(item); vm.myArray.push(item); }

这样一来,当事情发生在我观察的阵列,我知道这是添加的项目。

vm.myArray.subscribe(function(newArray) { var addedItem = vm.selectedItem(item); ... }

这真是啰嗦了,假设你的数组保存多种类型的数据,你需要有某种标志,可以帮助你知道如何使用您保存的变量做...

vm.myArray.subscribe(function(newArray) {
  if ( wasUpdated )
    // do something with selectedItem
  else
    // do whatever you whenever your array is updated
}

需要注意的重要一点是,你可能知道哪些项目,如果你知道是否加pushunshift使用。 只需浏览数组或第一个,瞧的最后一个项目。



Answer 6:

尝试vm.myArray().arrayChanged.subscribe(function(eventArgs))

具有被添加的项目时的附加值,并且当一个项目被除去移除值。



文章来源: Subscribe to observable array for new or removed entry only