Aurelia:使用可重复使用的可验证自定义元素验证表单

Aurelia: validating form with reusable validatable custom element

小问题:当验证是子自定义元素的一部分时,如何验证父表单?

长版:

我构建了一个可重复使用的自定义元素,其中包括验证,它的工作方式与我预期的一样:

验证-input.html:

<template>
<div class="form-group" validate.bind="validation">
    <label></label>
    <input type="text" value.bind="wert" class="form-control" />
</div>
</template>

验证-input.js:

import { bindable, inject } from 'aurelia-framework';
import { Validation } from 'aurelia-validation';

@inject(Validation)
export class ValidatedInputCustomElement {
    @bindable wert;

    constructor(validation) {
        this.validation = validation.on(this)
        .ensure('wert')
            .isNotEmpty()
            .isGreaterThan(0);
    }
} 

我会有一些表单在同一视图中多次使用此自定义元素(最多可达 8 次或 12 次甚至更多)。一个非常简化的示例可能如下所示:

<template>
  <require from="validated-input"></require>
  <form submit.delegate="submit()">
    <validated-input wert.two-way="val1"></validated-input>
    <validated-input wert.two-way="val2"></validated-input>
    <validated-input wert.two-way="val3"></validated-input>
    <button type="submit" class="btn btn-default">save</button>
  </form>
</template>

在相应的viewmodel文件中,我想确保只有在一切都有效的情况下才能提交数据。我想做类似

的事情
this.validation.validate()
    .then(() => ...)
    .catch(() => ...);

但我还不明白如何(或是否)可以将整体验证拉入父视图。

到目前为止我想到的是像这样引用我的验证输入的视图模型:

<validated-input wert.two-way="val1" view-model.ref="vi1"></validated-input>

然后像这样在父级中检查它:

this.vi1.validation.validate()
    .then(() => ...)
    .catch(() => ...);

但这会让我需要调用它 8/12/... 次。

我可能会在表单中包含一些额外的验证。

这是一个带有示例的插件: https://plnkr.co/edit/v3h47GAJw62mlhz8DeLf?p=info

but this would make me need to call it 8/12/... times.

And I will probably have some additional validation included in the form.

这些台词对我来说很重要。在我看来(考虑到你不想调用 8/12 次,而且你还需要额外的验证),你应该验证整个表单,而不是每个元素。在这种情况下,您可以在根组件(或拥有表单的组件)中注入验证,如下所示:

import { Validation } from 'aurelia-validation';
import { bindable, inject } from 'aurelia-framework';

@inject(Validation)
export class App {
  val1 = 0;
  val2 = 1;
  val3 = 2;
  
  resulttext = "";
  
  constructor(validation) {
    this.validation = validation.on(this)
      .ensure('val1')
        .isNotEmpty()
        .isGreaterThan(0)
      .ensure('val2')
        .isNotEmpty()
        .isGreaterThan(0)
      .ensure('val3')
        .isNotEmpty()
        .isGreaterThan(0);
     //some additional validation here
  }
  
  validate() {
    this.validation.validate()
        .then(() => this.resulttext = "valid")
        .catch(() => this.resulttext = "not valid");
  }
}

查看:

<template>
  <require from="validated-input"></require>
  <form submit.delegate="validate()" validation.bind="validation">
    <validated-input wert.two-way="val1"></validated-input>
    <validated-input wert.two-way="val2"></validated-input>
    <validated-input wert.two-way="val3"></validated-input>
    
    <button type="submit" class="btn btn-default">validate</button>
  </form>
  <div>${resulttext}</div>
</template>

现在,您可以在其他地方重复使用 validated-input 组件。当然,您可能必须重命名它,因为名称 validated-input 在这种情况下没有意义。

这是 plunker 示例 https://plnkr.co/edit/gd9S2y?p=preview


另一种方法是将所有验证对象放入一个数组,然后调用一个函数来验证所有验证对象,但这对我来说听起来很奇怪。

希望对您有所帮助!

您可以在表单级别定义一组验证对象(如 Fabio Luz 所写),然后在该数组中注册自定义元素验证。验证将在表单提交时开始。

表单代码如下:

validationArray = [];

validate() {
    var validationResultsArray = [];

    // start the validation here
    this.validationArray.forEach(v => validationResultsArray.push(v.validate()));

    Promise.all(validationResultsArray)
        .then(() => this.resulttext = "validated")
        .catch(() => this.resulttext = "not validated");
}

validated-input.js 获取一个新函数来注册验证

bind(context) {
    context.validationArray.push(this.validation);
}

plunker 示例在这里 https://plnkr.co/edit/X5IpbwCBwDeNxxpn55GZ?p=preview