动态重新绑定扩展程序不会更新视图

时间:2018-02-16 20:11:15

标签: knockout.js

我有一个扩展程序可以检查目标的最小/最大长度。我需要根据下拉选择动态设置最小/最大值。如果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() } "/>

1 个答案:

答案 0 :(得分:0)

我认为你不能在运行时更改KO扩展器的值。但我之前从未这样做过,所以我尝试将observable传递给扩展器,然后在.subscribe()回调中更改那些可观察的值,但没有运气。

我建议使用计算机代替。看起来您可以访问视图模型中所需的所有值。

&#13;
&#13;
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;
&#13;
&#13;