公开访问对象aurelia验证的对象

时间:2017-09-29 19:43:49

标签: aurelia aurelia-validation

我想公开访问私有属性,其中对象存储在当前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;
  }

1 个答案:

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