4

所以我使用Knockout Validation来验证我的viewmodel和一个自定义的knockout datepicker bindingHandler来附加一个jQuery-UI日期选择器来动态添加我的observableArray中的项目。Knockout验证不与DatePicker bindingHandler配合使用

看来我的bindingHandler正在销毁或破坏该字段上的验证规则。开始或结束日期的验证规则似乎都没有得到执行。

JSFiddle Link of my code

HTML代码:

<form> 
    <a class="btn btn-default" data-bind="click: function() { $root.addMed(); }">Add New Medication</a> 

    <h6 data-bind="visible: patientMeds().length < 1">No medications entered.</h6> 

    <table class="table table-condensed" data-bind="visible: patientMeds().length > 0"> 
     <thead> 
      <tr> 
       <th>Med</th> 
       <th>From</th> 
       <th>To</th> 
       <th></th> 
      </tr> 
     </thead> 
     <tbody data-bind="foreach: patientMeds"> 
      <tr> 
       <td> 
        <input class="form-control" data-bind="value: MedicationID" /> 
       </td> 
       <td> 
        <input class="form-control" data-bind="datepicker: StartDate, datepickerOptions: { changeMonth: true, changeYear: true, showButtonPanel: true }" /> 
       </td> 
       <td> 
        <input class="form-control" data-bind="datepicker: DiscontinuedDate, datepickerOptions: { changeMonth: true, changeYear: true, showButtonPanel: true }" /> 
       </td> 
       <td> 
        <button class="btn btn-default" data-bind="click: $parent.removeMed">Delete</button> 
       </td> 
      </tr> 
     </tbody> 
    </table> 
</form> 

的Javascript /视图模型的代码:

ko.bindingHandlers.datepicker = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     var options = allBindingsAccessor().datepickerOptions || {}; 

     $(element).datepicker(options); 

     //handle the field changing 
     ko.utils.registerEventHandler(element, "change", function() { 
      var observable = valueAccessor(); 
      observable($(element).datepicker("getDate")); 
     }); 

     //handle disposal (if KO removes by the template binding) 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).datepicker("destroy"); 
     }); 

    } 
}; 

function PatientMedication(p) { 
    var self = this; 
    p = p || {}; 

    self.MedicationID = ko.observable(p.MedicationID || 1) 
     .extend({ 
     required: { 
      params: true, 
      message: 'Please enter a medication' 
     }, 
     number: true 
    }); 
    self.StartDate = ko.observable(p.StartDate).extend({ 
     required: { 
      params: true, 
      message: 'Please enter a date' 
     }, 
     date: true 
    }); 

    self.DiscontinuedDate = ko.observable(p.DiscontinuedDate || '').extend({ 
     required: { 
      params: true, 
      message: 'Please enter a date' 
     }, 
     date: true 
    }); 
} 

function MedicationViewModel() { 
    var self = this; 

    self.patientMeds = ko.observableArray([]); 

    self.addMed = function() { 
     self.patientMeds.unshift(new PatientMedication()); 
    }; 

    self.removeMed = function (med) { 
     self.patientMeds.remove(med) 
    }; 
}; 

var medvm = new MedicationViewModel(); 
ko.applyBindings(medvm); 

回答

9

验证插件仅钩入valuecheckedtextinputselectedOptions绑定。

如果你想使你的自定义绑定触发你需要调用插件的validation.makeBindingHandlerValidatable方法,并将您的自定义绑定名称的验证:

ko.bindingHandlers.datepicker = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     //... 
    } 
}; 
ko.validation.makeBindingHandlerValidatable('datepicker'); 

演示JSFiddle