2017-09-29 9 views
0

addObject()を発行するときと同じようにオブジェクトが現在のValidationControllerに格納されているプラ​​イベートプロパティをパブリックアクセスしたいと思います。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()を呼び出すようになります。

スコアオブジェクトがあると仮定します。「コンテナ」にスコアのruleValidatorを解決し、次のように検証チェーンを構築します。ここ

@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が持っているので、それらのオブジェクトのトラックは、それへのアクセス権を持っている素晴らしいものです。 ..

export interface IRuleValidator { 
    addRules(model:any, models:any[]): void; 
} 

をのでよう..これらすべてのオブジェクトを収集チェーンのルートから空の配列を渡す

:オプションMeanwile

は、次のようにバリデータクラスを書き換えるインターフェイスをリファクタリングであります

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

しかしSINCと..プロセスを蹴ります私たちは、ValidationControllerでこのプロパティを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型は、以下のインタフェースを実装します。そのオブジェクト/ sの検証

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の準備ができている場合は通知するためにフィールドを更新するために従うよう、我々はコードをsimplyfy可能性がイベントオブジェクト であり、すでにあります。

this.validationController.subscribe(validateEvent => this.isFormValid = validateEvent.results.every(result => result.valid)); 
関連する問題