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

时间:2016-02-25 10:32:56

标签: aurelia aurelia-validation

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

长版:

我构建了一个可重用的自定义元素,其中包含的验证工作正如我期望的那样:

验证-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(() => ...);

但我不明白如何(或者如果)我可以将整体验证拉到父视图中。

到目前为止,我想到的是引用我的验证输入的viewmodel,如下所示:

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

然后在父母身上检查它:

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

但这会让我需要称它为8/12 / ......次。

我可能会在表格中加入一些额外的验证。

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

2 个答案:

答案 0 :(得分:1)

您可以在表单级别定义验证对象数组(如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

答案 1 :(得分:0)

  

但这会让我需要称它为8/12 / ......次。

     

我可能会在表格中加入一些额外的验证。

这些线对我来说非常重要。在我看来(考虑到您不想调用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

另一种方法是将所有验证对象推送到一个数组中,然后调用一个函数来验证所有验证对象,但这听起来很奇怪。

希望它有所帮助!