我正在尝试使用ko.validation验证列表中的条目是否与列表中的所有其他条目都是唯一的,但是在运行验证时我遇到了问题。
我有一个可编辑的列表(ko.observableArray
),该数组中的每个项目都是一个视图模型,上面有ko.observable
:
var vm = function (data) {
var self = this;
self.items = ko.observableArray();
_.each(data.words, function (word) {
self.items.push(new listItemVm({parent: self, word: word.word}));
});
};
var listItemVm = function (data) {
var self = this;
self.parent = data.parent;
self.word = ko.observable(data.word);
};
然后我向listItemVm.word
ko.observable添加一些验证。我希望每个人都是独一无二的:
var listItemVm = function (data) {
var self = this;
self.parent = data.parent;
self.word = ko.observable(data.word).extend({
validation: {
validator: function (name, params) {
console.log("validating " + name);
// word we are editing must be different from all other words
// uncommenting this next line causes the behaviour
// I would expect because params.parent.items()
// is not called
//return true;
var allWords = params.parent.items();
// exclude current view model we are editing
var otherWordViewModels = _.filter(allWords, function (row) {
return row !== params.currentRow;
});
var otherWords = _.map(otherWordViewModels, function (item) {
return item.word();
});
return !_.contains(otherWords, name);
},
message: 'Must be unique',
params: {
currentRow: self,
parent: self.parent
}
}
});
};
我给它一些数据,并将其包装在一些HTML中:http://jsfiddle.net/9kw75/3/
现在,这确实工作 - 验证运行正确并且当两个输入的值相等时显示无效 - 但是看看控制台上的那个小提琴。为什么验证例程在加载时运行三次,为什么两个字段只在一个值更新时验证?
值得注意的是,只有在验证器中读取params.parent.items()
后才能观察到这种奇怪的行为。如果返回被注释掉,我会发现我期望的行为。
答案 0 :(得分:2)
我相信它的工作方式是“验证器”函数用于计算的observable。因此,在执行时读取的任何可观察对象现在都是依赖性用于计算。由于您正在阅读此函数中每个项目的word
可观察项,因此每个项目都会触发所有其他项目的验证。
它是有意义的,它以这种方式工作,但在您的特定应用程序的情况下,它没有意义。您可以使用peek
来读取observable而不触发依赖项检测:
var allWords = params.parent.items.peek();
// ...
var otherWords = _.map(otherWordViewModels, function (item) {
return item.word.peek();
});