我使用KnockoutJS和Knockout-Validation插件來驗證表單上的字段。我在使用本機驗證規則驗證某個值是唯一值時遇到問題 - 我使用Ryan Niemeyer的編輯器模式允許用戶編輯或創建Location
。這是我的fiddle,以查看我的問題的完整。Knockout-Validation插件的獨特值驗證
function Location(data, names) {
var self = this;
self.id = data.id;
self.name = ko.observable().extend({ unique: { collection: names }});
// other properties
self.errors = ko.validation.group(self);
// update method left out for brevity
}
function ViewModel() {
var self = this;
self.locations = ko.observableArray([]);
self.selectedLocation = ko.observable();
self.selectedLocationForEditing = ko.observable();
self.names = ko.computed(function(){
return ko.utils.arrayMap(self.locations(), function(item) {
return item.name();
});
});
self.edit = function(item) {
self.selectedLocation(item);
self.selectedLocationForEditing(new Location(ko.toJS(item), self.types));
};
self.cancel = function() {
self.selectedLocation(null);
self.selectedLocationForEditing(null);
};
self.update = function(item) {
var selected = self.selectedLocation(),
updated = ko.toJS(self.selectedLocationForEditing()); //get a clean copy
if(item.errors().length == 0) {
selected.update(updated);
self.cancel();
}
else
alert("Error");
};
self.locations(ko.utils.arrayMap(seedData, function(item) {
return new Location(item, self.types, self.names());
}));
}
雖然我有問題。由於正在編輯的Location
與locations
observableArray(請參見Location.edit
方法)「分離」,因此當我在分離的Location
中更改name
時,names
計算數組中的值未更新。因此,當驗證規則將它與names
數組進行比較時,它將始終返回有效狀態爲真,因爲計數器將只有1或0.(請參閱下面的淘汰算法驗證算法)
在options的參數unique
驗證規則我可以通過一個屬性爲externalValue
。如果這個值不是未定義的,那麼它將檢查匹配名稱的計數是大於還是等於1而不是2.除了用戶更改名稱,繼續到另一個字段,然後返回到名稱並想要將其更改回原始值。該規則只是看到該值已存在於names
數組中,並返回有效狀態爲false。
這裏是knockout.validation.js算法處理該unique
規則...
function (val, options) {
var c = utils.getValue(options.collection),
external = utils.getValue(options.externalValue),
counter = 0;
if (!val || !c) { return true; }
ko.utils.arrayFilter(ko.utils.unwrapObservable(c), function (item) {
if (val === (options.valueAccessor ? options.valueAccessor(item) : item)) { counter++; }
});
// if value is external even 1 same value in collection means the value is not unique
return counter < (external !== undefined && val !== external ? 1 : 2);
}
我想過用這個作爲基礎來創建自定義的驗證規則,但我一直被陷關於如何處理用戶想要回到原始值的情況。
我感謝任何和所有的幫助。
是,但我可以通過調用'self.selectedLocationForEditing處理新項目(new Location({},self.types,self.namesExceptCurrent('')));'。這是一個優雅,簡單的解決方案 - 謝謝nemesv! – bflemi3 2013-04-11 20:28:25
嗨nemesv這個小提琴現在不工作 – user2142786 2014-08-21 04:56:18
@ user2142786感謝您注意它,我現在修復它 – nemesv 2014-08-21 06:00:15