2013-01-04 46 views
66

所以,是的,我可以訂閱可觀察到的數組:訂閱新的或刪除條目可觀測陣列只

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

的問題是傳遞給函數的newVal是整個陣列。無論如何,我只能得到三角洲的一部分?說添加或刪除元素

回答

108

截至KnockoutJS 3.0,有上ko.observableArray一個arrayChange subscription option

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"); 
+0

什麼是一個「修改」個人地位? – beauXjames

+0

當你說「修改個人」時,我不明白你在問什麼。 –

+0

個人==變化的情況下==改變 [「添加」,「刪除」,「???」,「???」,... ???] – beauXjames

-1

沒有,我知道的。想知道我在做什麼?我使用一個變量來保存的價值,一種叫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使用加入。只需瀏覽數組的最後一項或第一個項目即可。

+0

我正在使用一種不同的方法:跟蹤一個元素是否已經插入元素本身。見我的回答上述 –

0

我使用的是類似的,但不同的方法,跟蹤是否一個元素在元素本身被裝備:

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(); 
     } 
     }) 
    } 
    }); 
}) 

但它是很乏味和在我的代碼

+0

爲了保存自己的屬性,可以使用: 如果(!(「顯示名」在El)){} – GrantDG

-1

嘗試的模式重複vm.myArray().arrayChanged.subscribe(function(eventArgs))

即具有被添加的項目時的附加值,並且當一個項目被除去移除值。

7

因爲我無法找到這個其他地方的任何信息,我會增加對如何與打字稿用這個答覆。

的關鍵在這裏是使用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"); 
} 
1

爲了只檢測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()的相似模式。