Is there a way to extend validation on Knockout Validation's validatedObservable?

时间:2016-04-04 16:55:32

标签: knockout.js knockout-validation

I need to make sure each observable is valid and also make sure all the observables are valid together. In my simplified example I have a modelNumber and stockNumber that are each required, but together they must also form a valid partNumber. My attempt gives me this error:

"Uncaught Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters."

What's the problem?

https://jsfiddle.net/yekr2ov2/18/

// enable validation
ko.validation.init();

ko.validation.rules['partNumberValid'] = {
  validator: function(partInfo, otherVal) {
    return partInfo.modelNumber() + partInfo.stockNumber() == "m1s1";
  },
  message: 'part number is invalid'
};
ko.validation.registerExtenders();

function VM() {
  var self = this;

  self.modelNumber = ko.observable().extend({ required: true });
  self.stockNumber = ko.observable().extend({ required: true });
  self.vinNumber   = ko.observable().extend({ required: true });

  self.isPartNumberValid = ko.validatedObservable({
    modelNumber: self.modelNumber,
    stockNumber: self.stockNumber,
    vinNumber: self.vinNumber
  }).extend({ partNumberValid: true });

  self.message = ko.observable();

  self.save = function() {
    if (self.isPartNumberValid.isValid()) {
      self.message("saved");
    } 
    else {
      debugger;
      //self.isPartNumberValid.errors.showAllMessages();
      self.message("not saved");
    }    
  };

}

ko.applyBindings(new VM());

2 个答案:

答案 0 :(得分:1)

我修改了代码,以下代码运行正常。

ko.validation.init();
ko.validation.rules['partNumberValid'] = {
 validator: function (partInfo, otherVal) {                           
              return partInfo.modelNumber() +''+ partInfo.stockNumber() === "m1s1";
            },
 message: 'part number is invalid'
           };
 ko.validation.registerExtenders();

 function VM() {
   var self = this;
   self.modelNumber = ko.observable().extend({required: true});
   self.stockNumber = ko.observable().extend({required: true});
   self.isPartNumberValid = ko.observable({                        
     modelNumber:self.modelNumber,
     stockNumber:self.stockNumber                                         
   }).extend({partNumberValid:true});

  self.validateMe = ko.computed(function(){
                        write:{
                            var tes = ko.validation.group([self.modelNumber,self.stockNumber,self.isPartNumberValid]);
                            tes.showAllMessages(true);
                        }
                    });
                }
  ko.applyBindings(new VM()); 

小提琴:https://jsfiddle.net/yekr2ov2/7/ 我使用ko.validation.group来验证observable并计算立即验证。您可以使用按钮单击或任何其他自定义功能替换计算。如果有帮助,请告诉我。

谢谢

答案 1 :(得分:0)

我认为答案是你无法在Knockout Validation的validatedObservable上扩展验证。我认为这里正确的答案是为需要验证的每件事或事物组创建observable,然后创建validatedObservable以验证所有observables

https://jsfiddle.net/yekr2ov2/17/

ko.validation.init();
ko.validation.rules['partNumberValid'] = {
  validator: function(partInfo, otherVal) {
    return partInfo.modelNumber() + partInfo.stockNumber() === "m1s1";
  },
  message: 'part number is invalid'
};
ko.validation.registerExtenders();

function VM() {
  var self = this;
  self.modelNumber = ko.observable().extend({ required: true });
  self.stockNumber = ko.observable().extend({ required: true });
  self.vinNumber = ko.observable().extend({ required: true });

  self.partNumber = ko.observable({
    modelNumber: self.modelNumber,
    stockNumber: self.stockNumber
  }).extend({ partNumberValid: true });

  self.isPartNumberValid = ko.validatedObservable({
    modelNumber: self.modelNumber,
    stockNumber: self.stockNumber,
    vinNumber: self.vinNumber,
    partNumber: self.partNumber
  });

  self.message = ko.observable();

  self.save = function() {
    if (self.isPartNumberValid.isValid()) {
      self.message("saved");
    } 
    else {
      debugger;
      self.isPartNumberValid.errors.showAllMessages();
      self.message("not saved");
    }    
  };

}
ko.applyBindings(new VM());