Knockout 订阅可观察的复杂对象的任何变化
Posted
技术标签:
【中文标题】Knockout 订阅可观察的复杂对象的任何变化【英文标题】:Knockout Subscribe to any change in observable complex object 【发布时间】:2015-01-17 01:54:56 【问题描述】:我有一个包含一个可观察对象的视图模型,它是用一个对象初始化的。 此对象本身包含可观察对象。
我的目标是在该对象发生更改时(或:当该对象中的任何可观察对象发生更改时)得到通知
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;
;
视图模型
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");
是否有可能对复杂对象的更改做出反应?任何帮助表示赞赏。
我已经尝试了来自 rpniemeyer 的dirtyFlag 解决方案(cmets 中的链接)。复杂对象上的脏标志的问题是,当它切换到“真”并且我正在订阅该标志时,这只是第一次可以。为了对进一步的变化做出反应,我需要再次将dirtyFlag设置为false(在订阅中完成我的工作之后)。这将导致订阅循环。
【问题讨论】:
This post 可能会帮助您入门。 这个插件似乎完全符合你的要求:github.com/ZiadJ/knockoutjs-reactor 【参考方案1】:您可以使用以下技巧:
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
会递归读取对象中的所有属性,从而使计算依赖于所有属性。
【讨论】:
请注意,只要对象的任何 非 可观察属性发生变化,这也将被调用,这可能是不需要的。 @tloflin 怎么样?不会对这些属性进行任何更改跟踪 提示:将 console.log 放入 subscribe 以检查它没有被调用太多次。您可以使用可观察的速率限制来避免过多的事件,如果字段是文本输入,这尤其有用。针对这种情况,在subscribe
函数之前添加 extend( rateLimit: 500 )
。我相信 rateLimit: 0
或 extend( deferred: true );
可能会很有用,如果您发现每次更改都会引发多个事件。
有没有一种简单的方法来确定哪个属性引发了更改事件?以上是关于Knockout 订阅可观察的复杂对象的任何变化的主要内容,如果未能解决你的问题,请参考以下文章
Knockout.js:当可观察数组中的值发生变化时触发计算的最佳方法是啥
在 knockout.js 中更改 observable 但不通知订阅者
Knockout JS 订阅 2 个 observables 的方式是,如果 2 个 observables 中的任何一个发生变化,我只会收到一次通知