2013-01-04 13 views

Trả lời

108

Kể từ KnockoutJS 3.0, có arrayChange subscription option trên 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!"); 

Trong callback ở trên, đối số thay đổi này sẽ là một mảng của các đối tượng thay đổi như thế này:

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

Đối với vấn đề cụ thể của bạn, bạn muốn được thông báo về mới hoặc gỡ bỏ mục. Để thực hiện điều đó bằng Knockout 3, nó sẽ giống như thế này:

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

trạng thái của cá nhân 'đã sửa đổi' là gì? – beauXjames

+0

Tôi không hiểu bạn đang hỏi gì khi nói "cá nhân đã sửa đổi". –

+0

cá nhân == thể hiện thay đổi == thay đổi ['đã thêm', 'đã xóa', '???', '???', ... ???] – beauXjames

-1

Không ai mà tôi biết. Muốn biết tôi làm gì không? Tôi sử dụng một biến trước để giữ giá trị, một cái gì đó gọi là selectedItem

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

Vì vậy, theo cách đó, khi có điều gì xảy ra với mảng quan sát của tôi, tôi biết được mục đã được bổ sung.

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

Điều này thực sự tiết, và giả sử mảng của bạn giữ nhiều loại dữ liệu, bạn sẽ cần phải có một số loại cờ giúp bạn biết phải làm gì với các biến đã lưu của bạn ...

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

Một điều quan trọng cần lưu ý là bạn có thể biết mục nào đã được thêm nếu bạn biết liệu push hoặc unshift đã được sử dụng chưa. Chỉ cần duyệt mục cuối cùng của mảng hoặc mảng đầu tiên và voila.

+0

Tôi đang sử dụng một cách tiếp cận khác: theo dõi liệu một phần tử đã được thiết kế trong chính phần tử đó chưa. Xem câu trả lời của tôi ở trên –

0

Tôi đang sử dụng một cách tiếp cận tương tự nhưng khác nhau, theo dõi xem một yếu tố đã được instrumented trong các yếu tố chính:

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

Nhưng nó thực sự tẻ nhạt và mô hình lặp đi lặp lại trên mã của tôi

+0

Để tiết kiệm cho mình một tài sản, bạn có thể sử dụng: nếu (! ('DisplayName' trong el)) {} – GrantDG

-1

Thử vm.myArray().arrayChanged.subscribe(function(eventArgs))

Điều đó có giá trị gia tăng khi một mục được thêm vào và giá trị đã xóa khi một mục bị xóa.

7

Vì tôi không thể tìm thấy bất kỳ thông tin về những nơi khác này, tôi sẽ thêm một câu trả lời về cách sử dụng này với nguyên cảo.

Chìa khóa ở đây là sử dụng giao diện KnockoutArrayChange làm TEvent để đăng ký. Nếu bạn không làm điều đó, nó sẽ cố gắng sử dụng đăng ký khác (không chung chung) và sẽ khiếu nại về trạng thái, chỉ mục và giá trị không tồn tại.

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

Để chỉ phát hiện push()remove() sự kiện, và không di chuyển các mục, tôi đặt một wrapper xung quanh những mảng chức năng quan sát được.

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

Chức năng đẩy ban đầu được lưu trữ trong bao bì, sau đó được phủ một lớp bọc cho phép tôi làm bất cứ điều gì tôi muốn với mục được đẩy trước hoặc sau khi được đẩy vào mảng.

Mô hình tương tự cho remove().

Các vấn đề liên quan