我想公开访问私有属性,其中对象存储在当前ValidationController上,就像我们发出addObject()时一样。
来自此博客:
http://www.jujens.eu/posts/en/2017/Jan/24/aurelia-validation/
我试图不仅验证WELL KNOWN对象,还验证ValidationController中注册的 所有对象
让我解释一下,我有一个名为
的界面export interface IRuleValidator {
addRules(model:any): void;
}
以及实现此类接口的类
export class AddressRuleValidator implements IRuleValidator {
addRules(address: Address) {
ValidationRules
.ensure((a: Address) => a.address)
.required()
.on(address);
}
}
export class EmailRuleValidator implements IRuleValidator {
addRules(email: Email) {
ValidationRules
.ensure((e: Email) => e.email)
.required()
.on(email);
}
}
export class PhoneRuleValidator implements IRuleValidator {
addRules(phone: Phone) {
ValidationRules
.ensure((p: Phone) => p.phone)
.required()
.on(phone);
}
}
@inject(AddressRuleValidator, PhoneRuleValidator, EmailRuleValidator)
export class PlayerRuleValidator implements IRuleValidator {
private readonly addressRuleValidator: IRuleValidator;
private readonly phoneRuleValidator: IRuleValidator;
private readonly emailRuleValidator: IRuleValidator;
constructor(addressRuleValidator: IRuleValidator, phoneRuleValidator: IRuleValidator, emailRuleValidator: IRuleValidator) {
this.addressRuleValidator = addressRuleValidator;
this.phoneRuleValidator = phoneRuleValidator;
this.emailRuleValidator = emailRuleValidator;
}
addRules(player: Player) {
ValidationRules
.ensure((p: Player) => p.firstName)
.required()
.on(player);
if (player.addresses && player.addresses.length > 0)
player.addresses.map(address => this.addressRuleValidator.addRules(address));
if (player.phones && player.phones.length > 0)
player.phones.map(phone => this.phoneRuleValidator.addRules(phone));
if (player.emails && player.emails.length > 0)
player.emails.map(email => this.emailRuleValidator.addRules(email));
}
}
@inject(PlayerRuleValidator)
export class ScoreRuleValidator implements IRuleValidator {
private readonly playerRuleValidator: IRuleValidator;
constructor(playerRuleValidator: IRuleValidator) {
this.playerRuleValidator = playerRuleValidator;
}
addRules(score: Score) {
ValidationRules
.ensure((s: Score) => s.factor)
.required()
.on(score);
if (score.player) { this.playerRuleValidator.addRules(score.player); }
}
}
每个类都知道如何验证传递给它的对象,并委托其他类验证" child "对象。
即:得分有玩家,玩家有电子邮件。
分数知道如何验证自己并委托玩家自己进行验证,玩家也可以使用电子邮件,电话,构建所有" 链"下来。
因此,构建" 验证链的整个过程"开始在图的根对象上调用addRules()。
假设我们有一个分数对象:我们从" 容器中解析"一个ruleValidator for Score并开始构建验证链,如下所示。
@inject(ScoreRuleValidator)
export class ScoreList extends BaseViewModel {
public isOk: boolean;
public score: Score
................ code removed for brevity (validation controller code )
@inject(ScoreRuleValidator)
constructor(ruleValidator: IRuleValidator) {
................ code removed for brevity (validation score object creation)
ruleValidator.addRules(this.score) //this call will start all the validation chain registration
this.validationController.validateTrigger = validateTrigger.changeOrBlur;
this.validationController.subscribe(event => this.validateAll())
}
}
private validateAll() {
this.validator
.validateObject(this.model)
.then(results => this.isOk = results.every(result => result.valid));
//HERE GOES THE PROBLEM SINCE ONLY SCORE is known, and what about score.player, and score.player.addresss[], score.player.phones[], score.player.emails[] and so on in the graph
//I WILL NEED to traverse all the chain and since ValidationController has track of those object will be greet to have access to them
}
此处出现的问题仅限于SCORE已知,并且图表中的score.player和score.player.addresss [],score.player.phones [],score.player.emails []等等如何?
我需要遍历所有链,因为ValidationController跟踪这些对象 将很棒 以便访问它。
Meanwile一个选项是重构接口,重写验证器类如下:
export interface IRuleValidator {
addRules(model:any, models:any[]): void;
}
并从链的根处传递一个空数组,收集所有这些对象..就像这样......
export class AddressRuleValidator implements IRuleValidator {
addRules(address: Address, models: any[]) {
ValidationRules
.ensure((a: Address) => a.type)
.required()
.on(address);
models.push(address);
}
并使用空数组[]
启动进程.. const objects: any[] = [];
ruleValidator.addRules(this.score, [])
但是因为我们确实在ValidationController上将此属性设为私有,请公开 ..(我将照顾不触及它,只需阅读)< / p>
BR
(然后...... validateAll的最终方法应该是这样的)
private async validateAll() {
for (let model of this.models) {
let results = await this.validator.validateObject(model);
if (results.some(result => !result.valid)) {
this.isOk = false;
return;
}
}
this.isOk = true;
}
答案 0 :(得分:0)
深入了解回调就是答案。
validationController.subscribe(event => this.validateAll())
传递给回调的事件对象是ValidateResult []的数组 ValidateResult类型实现以下接口。
export declare class ValidateResult {
rule: any;
object: any;
propertyName: string | null;
valid: boolean;
message: string | null;
private static nextId;
/**
* A number that uniquely identifies the result instance.
*/
id: number;
/**
* @param rule The rule associated with the result. Validator implementation specific.
* @param object The object that was validated.
* @param propertyName The name of the property that was validated.
* @param error The error, if the result is a validation error.
*/
constructor(rule: any, object: any, propertyName: string | null, valid: boolean, message?: string | null);
toString(): string | null;
}
所以验证的对象已经存在于事件对象中 我们可以简单地将代码如下所示更新一个字段,以表明htlm是否已准备就绪。
this.validationController.subscribe(validateEvent => this.isFormValid = validateEvent.results.every(result => result.valid));