2014-11-19 7 views
14

Ich habe ein Viewmodel, das eine Observable enthält, die mit einem Objekt initialisiert wird. Dieses Objekt selbst enthält Observable.Knockout Abonnieren Sie jede Änderung in beobachtbaren komplexen Objekt

mein Ziel benachrichtigt werden, sobald sich der Objektänderungen (oder: wenn eine beobachtbare dass Objektänderungen)

jsfiddle

komplexes Objekt:

var ns = ns || {}; 

ns.ComplexObj = function (item) { 
    var self = this; 

    if (!item) { 
     item = {}; 
    } 

    self.id = item.Id || ''; 
    self.company = ko.observable(item.Company || ''); 
    self.email = ko.observable(item.Email || ''); 

    self.company.subscribe(function() { 
     console.log('debug: company changed'); 
    }); 

    return self; 
}; 

Ansichtsmodell

ns.mainvm = function() { 
    var simpleObject = ko.observable('i am pretty simple'); 

    simpleObject.subscribe(function (newValue) { 
     document.getElementById('simpleSubscribtionFeedback').innerText = newValue; 
    }); 

    var complexObject = ko.observable(ns.ComplexObj()); 
    complexObject.subscribe(function (newValue) { 
     // i would like to react to any change in complex object 
     document.getElementById('complexSubscribtionFeedback').innerText = 'i dont get executed :('; 
    }); 

    return { 
     simpleObject: simpleObject, 
     complexObject: complexObject 
    }; 
}; 

Bindung

var container = document.getElementById('wrapper'); 
if (container) { 
    ko.applyBindings(ns.mainvm, container); 
} else { 
    console.warn("container for binding ko not found"); 
} 

gibt es keine Möglichkeit zu Änderungen an einem komplexen Objekt zu reagieren? jede Hilfe wird geschätzt.

habe ich schon die driyFlag-Lösungen ausprobiert (Link in den Kommentaren), von rpniemeyer. Das Problem mit einem dreckigen Flag auf dem komplexen Objekt ist, dass, wenn es auf "wahr" wechselt und ich mich in das Abonnement dieses Flags einnehme, das nur zum ersten Mal in Ordnung ist. Um auf weitere Änderungen zu reagieren, müsste ich das dreckigeFlag wieder auf false setzen (nachdem ich meine Sachen im Abonnement gemacht habe). was zu einer Subskriptionsschleife führen würde.

+0

[Dieser Beitrag] (https://roysvork.wordpress.com/2014/01/12/tracking-changes-to-complex-viewmodels-with-knockout-js/) könnte Sie beginnen. – Michael

+0

danke für deinen Kommentar! Ich habe meine Frage unten bearbeitet. –

+1

Dieses Plugin scheint genau das zu tun, was Sie ned: https://github.com/ZiadJ/knockoutjs-reactor – Domysee

Antwort

29

können Sie die folgenden Trick verwenden:

ko.computed(function() { 
    return ko.toJSON(complexObject); 
}).subscribe(function() { 
    // called whenever any of the properties of complexObject changes 
}); 

Siehe http://jsfiddle.net/xcajt4qn/3/

Der Grund, warum dies funktioniert, ist ko.toJSON werden alle Objekte im Objekt rekursiv gelesen, also die berechnete abhängig machen alle Eigenschaften .

+2

schön, vielen Dank! –

+3

Sie sind verrückt nach diesem Trick. Aber auch super. – kernel

+4

Beachten Sie, dass dies auch immer dann aufgerufen wird, wenn sich eine der * * * * * * * * * * * - * * * * - * - * - * - * - * - * - * - * - * - * * * * * * * * * * * * * * * - * * * * * - * - * - Observiereigenschaften ändert. – tloflin

Verwandte Themen