2017-09-29 25 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));