Closed y2k4life closed 8 years ago
Time has passed and by now I have implemented my ideas. All the changes take place in the validation-controller.js
. With that said if you look at the links mentioned in my previous post the ideas and the design I want is there. I removed the injection of the Validator from ValidationController. I add an array validators = [];
. I added a method to ValidationController
to add a vlidator to the controller.
addValidator(validator: Validator) {
this.validators.push(validator)
}
Then I changed the _validateBinding
method to iterate through the validators until either an error occurs or all validation is completed.
_validateBinding(binding) {
const { target, rules, errors } = this.bindings.get(binding);
const { object, property } = getPropertyInfo(binding.sourceExpression, binding.source);
var newErrors;
for(let i=0; i < this.validators.length; i++) {
newErrors = this.validators[i].validateProperty(object, property, rules);
if(newErrors.length > 0) {
break;
}
}
this._updateErrors(errors, newErrors, target);
return errors;
}
Then in my view model I add the validators shown below. The first one added is the aurelia-validatejs and the second one is a custom validator I built that calls a function to test for validation. There might be more to this than I lead on, but that is more of how I implement FunctionValidator
and how I setup rules. The point here is that I can now use two different validators for one VM.
this.controller.addValidator(new Validator());
this.controller.addValidator(new FunctionValidator());
I think we can support multiple validator implementations pretty easily. We'll need to change the validation controller class's @inject(Validator)
to @inject(All.of(Validator))
and update the validateBinding method as you've done.
But would inject all Validator
(s) be a good design? What if on some cases I don't need all? Would injecting them be overkill? I like that idea because then one does not need to add them. These are the trade offs, lean and mean vs. I forgot to add my validator. I guess it is also the 80/20 rule how many times will there be more than one and does inject all only injects one for 80% of the time. I won't loss sleep over it either way :)
We can have both APIs (registration & add/remove validator). Then folks can decide for themselves.
closing- this was added in friday's release.
I see that the plugin aurelia-validatejs registers a validator into the aurlia global container
config.container.registerInstance(ValidatorInterface, new Validator());
. Then it is injected into theValidationController
as this@inject(Validator)
and I assume this is a singleton. But what if or how would I use multiple Validators? I know as of now I can't. If this could happen I already see that if a validator is called it does not do validation unless there are rules. So even if I have multple validators, if for a give viewmodel I did not setup up rules for a validator then it will not validate. I also understand that each validator will have different rules. My custom validator will not get overlapped with the validatejs rules. But with my idea I would not add a validator to the ValidateController unless I needed it.I built a validator to handle a more complex situation, but I still want to use aurelia-validatejs to handle the more mundane validations. I have a form with 5 or 6 simple none complex questions that are required. Some are number fields. For those I use the aurelia-validatejs validtor and the other complex questions I use my custom validator.
I know how I might change the
VlidationController
, but I don't know the time to live on theValidationController
and if I add a validator to handle form A how do I know that it is not there when I want to handle form B which has a different complex validator along with the validatejs. I'm reading about theNewInstance.of(ValidationController)
DI call. I think I would be safe base on thisIn this case it's telling the container to always retrieve a new instance of a ValidationController.
that I could then have an array of validators and methods on theValidationController
to add validators. Then change the logicconst newErrors = this.validator.validateProperty(object, property, rules);
to loop through each validator and callvalidateProperty.
Here is the live example: http://direct.axa.minico.forebrain.net/app/index.html
If you scroll down and hit continue to the "location" information there are yes/no and multiple choice questions which present more questions that are only required based on the answer. If you answer "Apartment/Condo" to the Location Type question then Door Man, Unit Number, and Floor Number are required. But if you select Storage Unit then those question are not required, but Facility Name, Unit #, and Floor # are required, but if you select Single Home then none of those are required. I can write the logic for validation in a customer validator, but how do I use my custom validator along with ValidateJs to handle the Address, City, State, and Zip, or to make sure Year Built is required and is a number.
If you hit continue to "additional info" you now have a different form with again complex validation. How do I remove the location validator and add the additional info validator and yet keep the validatjs? On this one, if you answer yes to prior losses I need to test if you have added any additional data and if you did not that is an error with at least one required. The last question answer yes and if you hit yes but don't add then that is a validation error.
All this came about when I built my custom validator and my custom validations work, but the other validation for validatejs did not work.