2017-09-29 45 views
0

我会喜欢公开访问私有财产的对象存储在当前ValidationController对象,当我们发出addObject()。公共访问对象prourery上aurelia验证

从这个博客:

http://www.jujens.eu/posts/en/2017/Jan/24/aurelia-validation/

我想不仅是验证一个众所周知的对象,但所有对象在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); } 
    } 
} 

每个类都知道如何验证传递给它,并委托给其他类“孩子”对象的验证对象。

即:分数有一名球员,一名球员有电子邮件。

分数知道如何验证自己和代表球员他自己的验证和球员做同样的电子邮件,电话,buildin所有“”下来。

因此,构建“验证链”的整个过程开始在图的根对象上调用addRules()。

假设我们有一个评分对象:我们从“容器”解决Score的一个ruleValidator并开始buildind验证链,如下所示。

@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.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, []) 

但正弦e我们在验证控制器上有这个属性private,请公开 ..(我会照顾不接触的,只是读它

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

一个深沉的样子回调是答案。

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; 
} 

所以对象/ s的验证是在事件对象 已经在那里我们可以simplyfy代码如下更新场信号是否为HTLM已准备就绪。

this.validationController.subscribe(validateEvent => this.isFormValid = validateEvent.results.every(result => result.valid));