2017-09-29 6 views
0

addObject()를 실행할 때 객체가 현재 ValidationController에 저장된 개인 속성을 공개 액세스하고 싶습니다. 이 블로그에서aurelia 유효성 검사에서 객체에 대한 공개 액세스

:

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

나는뿐만 아니라 잘 알려진 개체를 확인하려고하지만 ALL은 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); } 
    } 
} 

각 클래스가 다른 클래스에 위임에 "아이"객체의 검증을 통과 객체의 유효성을 검사하는 방법을 알고 있습니다.

예 : 점수에 플레이어가 있고 플레이어에 이메일이 있습니다.

점수는 자신에게 유효성을 검사하고 플레이어에게 자신의 유효성 검사를 위임하는 방법을 알고 있으며 플레이어는 전자 메일, 전화와 함께 모든 작업을 수행합니다. "체인"

따라서 "유효성 검사 체인"을 빌드하는 전체 프로세스는 그래프의 루트 객체에서 addRules()를 호출하기 시작합니다.

점수 객체가 있다고 가정합니다. "컨테이너"점수에 대한 ruleValidator를 확인하고 유효성 검사 체인을 buildind 시작합니다. HERE

@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.emails 그리고, [] score.player.phones, score.player 대한 ONLY SCORE가 공지되어 있기 때문에 문제가 무엇을 진행하고, [] score.player.addresss 그래프에?.

나는 모든 체인을 통과해야합니다 및 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, []) 

그러나 싱크와 .. 프로세스 킥 우리는 ValidationController에서이 속성을 private으로 유지하고 있습니다. 은 public으로 지정하십시오. ..

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