在knockout.js中创建脏标志绑定
我正在尝试创建一个绑定处理程序,它允许我跟踪绑定中使用的任何值是否已更改:在knockout.js中创建脏标志绑定,knockout.js,Knockout.js,我正在尝试创建一个绑定处理程序,它允许我跟踪绑定中使用的任何值是否已更改: <div id="container1" data-bind="dirty: $root.container1Dirty"> <span data-bind="visible: $root.container1Dirty">*</span> <label> Text 1 <input data-bind="value:
<div id="container1" data-bind="dirty: $root.container1Dirty">
<span data-bind="visible: $root.container1Dirty">*</span>
<label>
Text 1
<input data-bind="value: $root.text1" />
</label>
</div>
我希望ko.applybindingstosubjects
能够订阅该容器中所有绑定中使用的可观察对象。然而,情况似乎并非如此;看
有没有其他方法可以做到这一点?或者最好为每个容器创建一个ViewModel,然后使用?不确定这是否是最好的解决方案,但您可以将脏标志包装到一个“基类”中,并保持视图模型之间的所有逻辑共享。例如:
<input type='text' data-bind="value: textBox, event: { keyup: isDirty }">
<input type='button' value='click me if you can' data-bind="click: save, ,enable: isDirty">
var BaseViewModel = function (saveUrl, data) {
var self;
this.isDirty = ko.observable(false);
this.save = function(){
var jsData = ko.toJS(data);
alert('save: ' + jsData.textBox);
};
};
var pageViewModel = function(){
var self = this;
this.textBox = ko.observable('');
ko.utils.extend(self, new BaseViewModel('url for save', {textBox: self.textBox}));
}
ko.applyBindings(new pageViewModel());
var BaseViewModel=函数(saveUrl,数据){
var-self;
this.isDirty=ko.可观察(假);
this.save=函数(){
var jsData=ko.toJS(数据);
警报(“保存:”+jsData.textBox);
};
};
var pageViewModel=函数(){
var self=这个;
this.textBox=ko.可观察(“”);
extend(self,newbaseviewmodel('url for save',{textBox:self.textBox}));
}
应用绑定(新的pageViewModel());
如果您不想指定事件,只需对所有观察对象应用“脏”检查,您可以尝试以下操作:目前,我正在手动提供所有要跟踪的观察对象:
<input type='text' data-bind="value: textBox, event: { keyup: isDirty }">
<input type='button' value='click me if you can' data-bind="click: save, ,enable: isDirty">
var BaseViewModel = function (saveUrl, data) {
var self;
this.isDirty = ko.observable(false);
this.save = function(){
var jsData = ko.toJS(data);
alert('save: ' + jsData.textBox);
};
};
var pageViewModel = function(){
var self = this;
this.textBox = ko.observable('');
ko.utils.extend(self, new BaseViewModel('url for save', {textBox: self.textBox}));
}
ko.applyBindings(new pageViewModel());
<div id="container1" data-bind="
dirty: {
flag: 'container1Dirty',
target: [$root.text1]
}">
<span data-bind="visible: container1Dirty">*</span>
<label>
Text 1
<input data-bind="value: $root.text1" />
</label>
</div>
看
这并不是我真正希望的解决方案,因为我现在必须手动提供我想要跟踪的所有观察值,而不是自动查找所有使用的观察值。因此,我仍然希望找到更好的解决方案。@michaelpapworth我已经知道如何跟踪ViewModels的更改,但在这种情况下,我希望订阅特定元素中使用的所有观察值。这对我没有帮助。我希望能够自动检测元素内的更改,而不必向所有输入元素添加类似于
keyup:isDirty
的内容。我更新了答案,以继续使用相同的模式,但从输入中删除事件……这样,您仍然需要手动订阅所有要观看的观测值。但我希望通过应用自定义绑定,自动监视/订阅特定容器(元素)中使用的所有可观察对象。
ko.bindingHandlers.dirty = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var data = valueAccessor();
var dirtyObservable = ko.observable(false);
var orgValue = ko.toJSON(data.target);
var extraBinding = {};
extraBinding[data.flag || 'dirty'] = dirtyObservable;
var innerBindingContext = bindingContext.extend(extraBinding);
ko.applyBindingsToDescendants(innerBindingContext, element);
var dirty = ko.computed(function() {
return orgValue !== ko.toJSON(data.target);
});
dirty.subscribe(function(isDirty) {
dirtyObservable(isDirty);
});
return { controlsDescendantBindings: true };
}
};
ko.applyBindings({
text1: ko.observable('text1'),
text2: ko.observable('text2')
});