我有一个扩展程序可以检查目标的最小/最大长度。我需要根据下拉选择动态设置最小/最大值。如果min / max超出范围,则observable有一个hasError
,它将使用css类更新我的视图。问题是,一旦我重新绑定扩展器,视图就不会更新。这是我的扩展器:
ko.extenders.minmaxlength = function (target, options) {
target.min = ko.observable(options.min);
target.max = ko.observable(options.max);
target.hasError = ko.observable(false);
function validate(newValue) {
if (newValue.length > options.max || newValue.length < options.min){
target.hasError(true);
} else {
target.hasError(false);
}
}
validate(target());
target.subscribe(validate);
};
这是我重新绑定绑定并重新绑定扩展器的地方:
self.newValue = ko.observable('').extend({ minmaxlength: { min: 3, max: 30 } }); // defaults
self.selectedType.subscribe(function (newValue) {
if (newValue == undefined) {
return;
}
var obj = self.pricingTypes().filter(function (i) {
return i.Id == newValue;
});
if (obj.length > 0) {
var objType = obj[0];
self.selectedTypeObj(ko.mapping.fromJS(objType));
// rebind the extender here
self.newValue = ko.observable('').extend({ minmaxlength: { min: self.selectedTypeObj().MinLength(), max: self.selectedTypeObj().MaxLength() } });
self.newValue.valueHasMutated()
} else {
return; // bad value
}
});
当我调试时,我看到正在调用扩展器并正确设置hasError
功能,但同样,视图不会更新。
这是输入:
<input class="form-control" data-bind="textInput: $root.newValue, css: { 'requiredField': $root.newValue.hasError() } "/>
答案 0 :(得分:0)
我认为你不能在运行时更改KO扩展器的值。但我之前从未这样做过,所以我尝试将observable传递给扩展器,然后在.subscribe()
回调中更改那些可观察的值,但没有运气。
我建议使用计算机代替。看起来您可以访问视图模型中所需的所有值。
function TestViewModel() {
var self = this;
self.minLength = ko.observable(3); // default min
self.maxLength = ko.observable(30); // default max
self.newValue = ko.observable(null);
self.newValueIsValid = ko.pureComputed(function() {
if (!self.newValue()) {
return;
}
if (self.newValue().length > self.maxLength() || self.newValue().length < self.minLength()) {
console.log("invalid");
return false;
} else {
console.log("valid");
return true;
}
});
self.selectedType = ko.observable("default value");
self.selectedType.subscribe(function(newValue) {
self.minLength(5); // new min
self.maxLength(50); // new max
});
}
var vm = new TestViewModel();
ko.applyBindings(vm);
vm.newValue("test");
vm.newValueIsValid(); // should be valid with default min/max
vm.newValue("something really too long to be valid");
vm.newValueIsValid(); // should be invalid with default min/max
vm.selectedType("changed value");
vm.newValue("test");
vm.newValueIsValid(); // should be invalid with new min/max
vm.newValue("something really too long to be valid");
vm.newValueIsValid(); // should be valid with new min/max
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
&#13;