有没有反正我可以告诉knockout映射插件订阅所有属性更改调用某个函数?
我想能够一般地订阅,虽然,因为我的视图模型可能会有所不同,我不想硬编码的属性名称。我创建了一个函数来做到这一点,但它可能不是最好的方法。它可以在除IE7及以下的所有浏览器。
这里我使用viewmodel作为参数,并试图反思它订阅属性:
- function subscribeToKO(data) {
- $.each(data,function (property,value) {
- if (getType(value) == "Object")
- data[property] = subscribeToKO(value);
- else if (getType(value) == "Array") {
- $.each(value,function (index,item) {
- item = subscribeToKO(item);
- });
- }
- else {
- if (value.subscribe) {
- value.subscribe(function (newValue) {
- // do work
- });
- }
- }
- });
- return data;
- }
像我说的这样工作,但由于我使用映射pluging我希望有一个钩子,我可以使用提供一个函数,将一般订阅属性更改。
就像是:
- mapping = {
- create: function(options){
- options.data.subscribe(function(newValue){
- // do work ???
- });
- }
- }
- ko.mapping.fromJS(viewmodel,mapping);
有任何想法吗?
解决方法
这里是一个基于
Ryan Niemeyer’s dirty flag的通用方法。
点击这里查看 JsFiddle。
点击这里查看 JsFiddle。
Html:
- <ol>
- <li>
- Telephone : <input data-bind="value: telephone"/>
- </li>
- <li>
- Address : <input data-bind="value: address"/>
- </li>
- </ol>
Javascript:
- var model = {
- telephone: ko.observable('0294658963'),address: ko.observable('167 New Crest Rd')
- };
- // knockout extension for creating a changed flag (similar to Ryan's dirty flag except it resets itself after every change)
- ko.changedFlag = function(root) {
- var result = function() {};
- var initialState = ko.observable(ko.toJSON(root));
- result.isChanged = ko.dependentObservable(function() {
- var changed = initialState() !== ko.toJSON(root);
- if (changed) result.reset();
- return changed;
- });
- result.reset = function() {
- initialState(ko.toJSON(root));
- };
- return result;
- };
- // add changed flag property to the model
- model.changedFlag = new ko.changedFlag(model);
- // subscribe to changes
- model.changedFlag.isChanged.subscribe(function(isChanged) {
- if (isChanged) alert("model changed");
- });
- ko.applyBindings(model);