我有一个44可观察的淘汰模型。用户为它们选择值并单击提交按钮以将所选值存储在数据库中。如果没有为其中一个observable选择值,我想禁用该按钮。
var TestModel = function() {
self.Feedback1 = ko.observable();
self.Feedback2 = ko.observable();
..
self.Feedback44 = ko.observable();
self.IsEnabled = ko.observable(false);
self.Feedback1.subscribe(function(){
if (self.Feedback1() != undefined && .... self.Feedback44() != undefined) {
self.IsEnabled(true);
} else {
self.IsEnabled(false);
}
};
.
.
self.Feedback44.subscribe(function(){
if (self.Feedback1() != undefined && .... self.Feedback44() != undefined) {
self.IsEnabled(true);
} else {
self.IsEnabled(false);
}
};
};
<button data-bind="click: SubmitEvaluation,enable:IsEnabled">Submit Evaluation</button>
答案 0 :(得分:1)
将对属性的引用添加到数组中:
self.submitableProperties = [self.Feedback1, self.Feedback2, ..., self.Feedback44];
然后,扫描您的属性变得更加容易。
for (var i = 0; i < self.submitableProperties.length; i++) {
self.submitableProperties[i].subscribe(checkEnabled);
}
function checkEnabled() {
var anyUndefined = false;
for (var i = 0; i < self.submitableProperties.length; i++) {
if (self.submitableProperties[i]() === undefined) {
anyUndefined = true;
return;
}
}
self.IsEnabled(!anyUndefined);
}
答案 1 :(得分:1)
要完成您尝试使用最少量代码执行的操作,我将创建一个循环遍历viewmodel的所有可观察对象的计算器。
self.isEnabled = ko.computed(function() {
for (p in self) {
if (ko.isObservable(self[p])) {
if (self[p]() === null || self[p]() === undefined)
return false;
}
}
return true;
});
答案 2 :(得分:1)
我认为Marius建议的解决方案是最干净的方法。但是,检查可观察值是否为null或未定义是有点愚蠢 - 如果其中一个反馈可观察对象是空字符串,或者是否存在与表单无关但未定义的另一个可观察对象,该怎么办?在这两种情况下,您将遇到建议的解决方案的问题。因此,我们希望检测反馈可观察量并检查它们。有几种方法可以做到这一点,这里有几个:
在下面的jsfiddle中,我采用了第一种方法 http://jsfiddle.net/pardahlman/dz7UH/
self.AllQuestionsAnswered = ko.computed(function () {
for (p in self) {
if (ko.isObservable(self[p])) {
var isFeedback = p.indexOf('Feedback') != -1;
if (!isFeedback) {
continue;
}
var valueOfObservable = self[p]();
if (!valueOfObservable) {
return false;
}
}
}
return true;
});
答案 3 :(得分:1)
一个很好的方法,可以帮助您的应用程序的许多其他部分使用knockout.validation库:
https://github.com/Knockout-Contrib/Knockout-Validation
我创建了一个小提琴,演示了如何将其应用于您的场景。
http://jsfiddle.net/jiggle/2xAS7/
HTML:
<fieldset>
<legend>User: <span data-bind='text: errors().length'></span> errors</legend>
<label>Feedback 1: <input data-bind='value: feedback1' required/></label>
<label>Feedback 2: <input data-bind='value: feedback2' required/></label>
<label>
Subscriptions:
<select data-bind='value: feedback3, options: feedback3Options, optionsCaption: "Choose one..."' required></select>
</label>
<label>Feedback 4: <input data-bind='value: feedback4' required/></label>
<label>Feedback 5: <input data-bind='value: feedback5' required/></label>
<label>Feedback 6: <input data-bind='value: feedback6' required/></label>
<label>Feedback 7: <input data-bind='value: feedback7' required/></label>
</fieldset>
<button type="button" data-bind='click: submit'>Submit</button>
<button type="button" data-bind='click: submit, enable:isComplete'>Submit (disabled if not complete)</button>
<button type="button" data-bind='click: submit, enable:errors().length===0'>Submit (disabled if not complete)</button>
<br />
<br />
Display inline error messages? <input type="checkbox" data-bind='click: toggleInlineErrors,checked:showInlineErrors'/>
代码:
ko.validation.rules.pattern.message = 'Invalid.';
ko.validation.configure({
registerExtenders: true,
messagesOnModified: true,
insertMessages: true,
parseInputAttributes: true, //this is 'true' to read the 'required' attribute in your html
messageTemplate: null
});
var viewModel = {
feedback1: ko.observable(), //required attribute is set in the HTML
feedback2: ko.observable(), //required attribute is set in the HTML
feedback3: ko.observable(), //required attribute is set in the HTML
feedback4: ko.observable(), //required attribute is set in the HTML
feedback5: ko.observable(), //required attribute is set in the HTML
feedback6: ko.observable(), //required attribute is set in the HTML
feedback7: ko.observable().extend({ required: true }), //or add the required attribute when you create the observable
feedback3Options: ['Technology', 'Music'],
submit: function () {
if (viewModel.errors().length == 0) {
alert('Thank you.');
} else {
viewModel.errors.showAllMessages(this.showInlineErrors());
alert('Please check your submission.');
}
}
};
viewModel.showInlineErrors = ko.observable(true);
viewModel.errors = ko.validation.group(viewModel);
viewModel.isComplete = ko.computed(function(){
return viewModel.errors().length === 0
});
viewModel.toggleInlineErrors = function () {
viewModel.errors.showAllMessages(false);
return true;
};
addEventListener('load', function () {
ko.applyBindings(viewModel);
});
关键是ko.validation.group(viewModel),它将您的所有observable分组到一个组中,当您对viewmodel进行更改时,该组将被不断地(可观察)进行评估。
话虽如此,您可以进行数据绑定:&#39;启用:viewModel.errors.length === 0,点击:yourClickHandler&#39;或者创建一个计算的observable,如果没有错误,则返回true。
小提琴演示了两种选择。
它是一个优秀的库,非常强大,我创建的小提琴也演示了如何切换内联错误,只是给出一个整体消息(当你提交时),或突出显示缺少的内联条目,以便用户可以看到缺少的选项在哪里(如果您有44个用户需要完成的项目,可能非常有用!)。
希望有所帮助
(只包括kendo.validation.js(来自上面的github参考)到你的页面/包/模块,你可以开始使用它了)