可验证对象集合的敲除验证

Knockout Validation on Collections of validatable objects

所以我使用的是 Knockout 2.3 和 Knockout Validation 2.0.2。我有一个带有 属性 的 viewModel,它是自定义 javascript "objects" (HRAdmin) 的 observableArray。 HRAdmin 有 3 个属性需要验证。我很难处理这种情况。我尝试过不同的东西,但这是代码所在的位置。

为了简洁起见,我删除了我的 viewModel 的所有其他可以正常验证的属性。但这也告诉我的是我的其他代码的 none 正在干扰。

您可以 运行 并单步执行此处的代码,您会发现即使您将所有字段留空并单击 "Go to Step 3" link,这行代码始终会导致对象有效。

if (!obj[i].isValid())

它不应该是有效的。 Ideas/Suggestions??

   // check validity of each object in array
   ko.validation.rules['collectionValidator'] = {
     validator: function(obj, params) {
       for (var i = 0; i < obj.length; i++) {
         if (!obj[i].isValid()) {
           obj[i].notifySubscribers();
           return false;
         }
       }
       return true;
     }
   };

   // validate a certain number of object exist in array
   ko.validation.rules['minArrayLength'] = {
     validator: function(obj, params) {
       return obj.length >= params.minLength;
     },
     message: "Must have at least {0} {1}"
   };

   ko.validation.registerExtenders();


   // HRAdmin "object"
   function HRAdmin() {
     this.FirstName = ko.observable("").extend({
       required: true,
       minLength: 1,
       maxLength: 50
     });
     this.LastName = ko.observable("").extend({
       required: true,
       minLength: 1,
       maxLength: 50
     });
     this.Email = ko.observable("").extend({
       required: true,
       minLength: 1,
       maxLength: 100,
       email: true
     });
   }


   var viewModel = function() {

     var self = this;

     // Must be at least one HRAdmin and all fields of EACH HRAdmin must validate
     self.HrAdmins = ko.observableArray([ko.validatedObservable(new HRAdmin())]).extend({
       minArrayLength: {
         params: {
           minLength: 1,
           objectType: "Account Manager"
         },
         message: 'Must specify at least one Account Manager'
       },
       collectionValidator: {
         message: 'Please check the Account Manager information'
       }
     });

     self.AddHrAdmin = function(data, event) {
       self.HrAdmins.push(new ko.validatedObservable(new HRAdmin()))
     };

     self.GoToStep3 = function(data, event) {
       // validate at least one HRAdmin and ALL fields on each are valid          
       if (!self.HrAdmins.isValid()) {
         self.HrAdmins.notifySubscribers();
         return;
       }

       // on to step 3 ...
     };
   };

   ko.applyBindings(new viewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.2/knockout.validation.min.js"></script>


<div data-bind="foreach: HrAdmins">
  <input type="text" placeholder="First Name" data-bind="value: FirstName" />
  <input type="text" placeholder="Last Name" data-bind="value: LastName" />
  <input type="text" placeholder="Email Address" data-bind="value: Email" />
</div>
<p data-bind="validationMessage: HrAdmins" class="validationMessage"></p>
<a href="#" data-bind="click: $root.AddHrAdmin">Add Manager</a>
<a href="#" data-bind="click: $root.GoToStep3">Go to Step 3</a>

因此,在反复试验之后,我找到了解决方案。不确定这是否是最佳解决方案,但它工作正常。

我已经摆脱了 ko.validation.rules['collectionValidator'] 并添加了验证器分组。

self.HrAdminsErrors = ko.validation.group(self.HrAdmins, {deep: true, live: true});

操作代码在下面fiddle:

http://jsfiddle.net/3b3o87dy/6/