I use TS, but here is an example of how I am using it and it is working for me. Might not be the best way though.

In attached() I call a method setValidationRules() that setup the property validation requirements.

Initially I was setting up a rules collection and running them against the property, but changed that over to use the on() method. I left the full function as it shows how I was able to use a few of the more advance methods.

setValidationRules() { const RENTAL_NOTSELECTED = 0; const NOINSTRUCTOR = 0; const RENTAL_DUAL = 3; //this.studentRules = ValidationRules .ensure('wind').required() .ensure('expectedRunway').required() .ensure('fuelLeft').required() .ensure('fuelRight').required() .ensure('expectedFuelUsed').required() .ensure('weatherBriefed').satisfies((v, o: PaveTimecardData) => { return o.weatherBriefed; }) .on(this.paveTimecard.data); //.rules; //this.standardRules = ValidationRules .ensure('airport').required() .ensure('aircraftId').required() .ensure('timecardDate').required() .ensure('hobbsStart').required() .ensure('hobbsEnd').required() .ensure('rentalTypeId').satisfies((val, o: PaveTimecardModel) => { if (!o.rentalTypeId || o.rentalTypeId === RENTAL_NOTSELECTED) { return false; } return true; }) .withMessage("Rental Type needs to be selected.") .ensure('instructorId').satisfies((val, o: PaveTimecardModel) => { if (o.instructorId === NOINSTRUCTOR) { return false; } return true; }) .withMessage("Rental Type [Dual] requires instructor to be selected.") .when((o: PaveTimecardModel) => { return o.rentalTypeId === RENTAL_DUAL; }) .ensure('instructorId').satisfies((val, o: PaveTimecardModel) => { if (o.instructorId !== NOINSTRUCTOR) { let msg: string = "Rental Type does not require an instructor to be selected and will be removed on save."; if (this.warnings.indexOf(msg) === -1) { this.warnings.push(msg); } return true; } return true; }) .when((o: PaveTimecardModel) => { return o.rentalTypeId !== RENTAL_DUAL; }) .ensure('fuelAmount').satisfies((val, o: PaveTimecardModel) => { if (!o.fuelPurchased) { return true; } else if (o.fuelAmount && o.fuelAmount.length > 0) { return true; } return false; }) .when((o: PaveTimecardModel) => o.fuelPurchased) .withMessage("Purchased Fuel checked, no entry detected.") .on(this.paveTimecard); //.rules; }

I use it at various change events with the following code snippet:

this.vcontroller.validate() .then(result => { if(result.valid) this.enableSaveTimecard = true; });

I have a repeat.for in the template that displays any errors in validation that require action:

<div style="color: red;"> <ul if.bind="vcontroller.errors"> <li repeat.for="error of vcontroller.errors"> ${error.message} </li> </ul> </div>

Hope that helps somewhat.