父组件的 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: <code><pa-au-md-input label="some input label title" change.call="optionalChangeHandler(value, $event)" value.bind="optionalValueBind"/></code>
</p>
<pa-au-md-input label="password" value.bind="password & validate" type="password">
</pa-au-md-input>
<p>
Usage: <code><pa-au-md-input label="some input label title" change.call="optionalChangeHandler(value, $event)" value.bind="optionalValueBind"/></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);
我认为这很好。
我正在 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: <code><pa-au-md-input label="some input label title" change.call="optionalChangeHandler(value, $event)" value.bind="optionalValueBind"/></code>
</p>
<pa-au-md-input label="password" value.bind="password & validate" type="password">
</pa-au-md-input>
<p>
Usage: <code><pa-au-md-input label="some input label title" change.call="optionalChangeHandler(value, $event)" value.bind="optionalValueBind"/></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);
我认为这很好。