父组件的 Aurelia 火灾验证

Aurelia fire validation of parent component

我正在 aurelia 中开发自定义元素。并尝试对其进行验证。例如,假设我的应用程序组件中有一个表单,验证规则和控制器在该组件中定义如下:

@inject(NewInstance.of(ValidationController))
export class App {

  constructor(validationController) {
    this.validationController = validationController;

    ValidationRules
      .ensure('password')
      .required()
      .ensure('email')
      .email()
      .on(this);
  }

  clicked() {
    this.validationController.validate().then(console.log);
  }

}

我有一个像这样的自定义元素:

element.html

<template class.bind="statusClasses" validation-errors.bind="inputErrors">
  <input id.one-time="id" value.bind="value" type.bind="type" disabled.bind="disabled"
    change.delegate="change({ value: value, $event: $event })" />
  <label for.one-time="id">${label}</label>
  <span class="help-block" repeat.for="errorInfo of inputErrors">
    ${errorInfo.error.message}
  </span>
</template>

element.js

import { bindable, bindingMode, customElement, computedFrom } from 'aurelia-framework';

import './pa-au-md-input.css';

@customElement('pa-au-md-input')
export class PaAuMdInputCustomElement {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) value;
  @bindable label;

  @bindable doValidation = true;
  @bindable showValidationErrors = true;

  @bindable disabled = false;
  @bindable type = 'text';

  @bindable change = () => { console.debug(`change event of pa-au-md-input-${this.id} is un-used.`) };

  static nextId = 0; // babel way of #1

  constructor() {
    this.initializeVariables();
  }

  initializeVariables() {
    this.autoIncrementedId = PaAuMdInputCustomElement.nextId++;
    this.id = `pa-au-md-input#${this.autoIncrementedId}`;
  }

  @computedFrom('disabled')
  get statusClasses() {
    return ''
      + (this.disabled ? 'disabled' : '')
      + (this.showValidationErrors && this.inputErrors && this.inputErrors.length ? 'has-error' : '');
  }
}

以及这个自定义元素在里面的用法 app.html:

<template>
  <p>
    Usage:&nbsp;<code>&lt;pa-au-md-input label="some input label title" change.call="optionalChangeHandler(value, $event)" value.bind="optionalValueBind"/&gt;</code>
  </p>
  <pa-au-md-input label="password" value.bind="password & validate" type="password">
  </pa-au-md-input>
  <p>
    Usage:&nbsp;<code>&lt;pa-au-md-input label="some input label title" change.call="optionalChangeHandler(value, $event)" value.bind="optionalValueBind"/&gt;</code>
  </p>
  <pa-au-md-input label="email" value.bind="email & validate" type="email"></pa-au-md-input>
  <input type="password" value.bind="password & validate"/>
  <button click.delegate="clicked()">validate</button>

</template>

现在,如果我在 <pa-au-md-input label="email" value.bind="email & validate" type="email"></pa-au-md-input> 中输入一些无效的电子邮件,然后按验证按钮,那么它将被验证,一切都会正常进行。但它不检查模糊事件的验证规则。而在那之后的输入中,<input type="password" value.bind="password & validate"/> 对模糊进行了恰到好处的验证。那么问题是什么,如何解决呢?

您需要将内部输入的模糊事件转发到自定义元素容器(传播它)

element.html

<input id.one-time="id" value.bind="value" type.bind="type" disabled.bind="disabled" blur.delegate="forwardEvent($event)" change.delegate="change({ value: value, $event: $event })" />

以及JS文件中的变化

element.js

export class PaAuMdInputCustomElement {
// omited other codes
 forwardEvent(event) {
 this.element.dispatchEvent(clone(event));
 }
}

const clone = e => new e.constructor(e.type, e);

我认为这很好。