【问题标题】:Aurelia: validating form with reusable validatable custom elementAurelia:使用可重复使用的可验证自定义元素验证表单
【发布时间】:2016-02-25 10:32:55
【问题描述】:

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

加长版:

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

验证输入.html:

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

验证输入.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/... 次。

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

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

【问题讨论】:

    标签: aurelia


    【解决方案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

    【讨论】:

    • 这是一个不错的方法。它显着减少了所需的代码量。但是自定义元素必须知道父元素的 'validationArray' 属性,我可能会接受,但如果有人有没有这种耦合的解决方案,我将不胜感激。
    【解决方案2】:

    但这会让我需要调用它 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


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

    希望对你有帮助!

    【讨论】:

    • 我不想以这种方式验证,因为现在我需要编写ensure('val1') .isNotEmpty() .isGreaterThan(0) 8 或 12 或 ... 次,并且我需要轻松自定义或更改验证规则。对于另一个客户,它们会有所不同,这意味着要更改大量代码......这就是为什么我试图将验证(以及数字的格式/全球化等)合并到自定义元素中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 2019-10-04
    • 2012-03-13
    • 2018-03-20
    • 2013-05-24
    • 2020-07-24
    • 2018-03-18
    相关资源
    最近更新 更多