ko.validation を使用して、リスト内のエントリがリスト内の他のすべてのエントリから一意であることを検証しようとしていますが、実行すべきではない検証の実行に問題があります。
編集可能なリスト (a 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/
さて、これは機能します- 検証は正しく実行され、2 つの入力の値が等しい場合は無効と表示されます - しかし、そのフィドルでコンソールを見てください。ロード時に検証ルーチンが 3 回 5 回実行されるのはなぜですか? また、値が 1 つだけ更新されたときに両方のフィールドが検証されるのはなぜですか?
- ページの読み込み時
- 想定: 入力フィールドごとに検証が 1 回実行されます。
- Actual : 検証は、1 つの入力に対して 3 回実行され、もう 1 つの入力に対して 2 回実行されます。
- 値の更新時 (いずれかの入力フィールド)
- 予期される: 変更された入力フィールドに対してのみ検証が実行されます
- 実際: 両方の入力フィールドに対して検証が実行されます
この奇妙な動作はparams.parent.items()
、バリデータを読み取った後にのみ観察されることに注意してください。リターンがコメントアウトされている場合、私が期待する動作が観察されます。