2014-11-19 2 views
14

У меня есть viewmodel, который содержит наблюдаемый, который инициализируется объектом. Этот объект сам содержит наблюдаемые.Нокаут Подписываться на любые изменения в наблюдаемом сложном объекте

моя цель состоит в том, чтобы получать уведомления всякий раз, когда объект изменяется (или: когда любая наблюдаемая в том, что изменения объекта)

jsfiddle

сложный объект:

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

ViewModel

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

связывание

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

есть ли Possiblity реагировать на изменения на сложном объекте? любая помощь приветствуется.

Я уже пробовал решения dirtyFlag (ссылка в комментариях), от rpniemeyer. проблема с грязным флагом на сложном объекте заключается в том, что когда он переключается на «true», и я подключаюсь к подписке этого флага, это только нормально в первый раз. чтобы отреагировать на дальнейшие изменения, мне нужно снова установить dirtyFlag в false (после выполнения моих действий в подписке). который приведет к циклу подписки.

+0

[Это сообщение] (https://roysvork.wordpress.com/2014/01/12/tracking-changes-to-complex-viewmodels-with-knockout-js/) может вас завести. – Michael

+0

благодарит за комментарии! Я редактировал мой вопрос внизу. –

+1

Этот плагин, похоже, делает именно то, что вы сделали: https://github.com/ZiadJ/knockoutjs-reactor – Domysee

ответ

29

Вы можете использовать следующий трюк:

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

См http://jsfiddle.net/xcajt4qn/3/

Причину, почему это работает ko.toJSON рекурсивно прочитать все свойства в объекте, поэтому делают вычисленным зависит от всех свойств ,

+2

приятно, спасибо большое! –

+3

Ты злишься за то, что нашел этот трюк. Но и потрясающе. – kernel

+4

Обратите внимание, что это также будет вызываться всякий раз, когда изменяется любое из свойств объекта * non * -observable, что может быть нежелательным. – tloflin

Смежные вопросы