【问题标题】:Template Driven Forms required allows empty string - Angular 7/8所需的模板驱动表单允许空字符串 - Angular 7/8
【发布时间】:2019-10-15 13:26:24
【问题描述】:

我的表单验证允许空字符串时遇到问题。 required 有效,但允许用户单击空间。我在网上找到的解决方案是使用 ng-pattern pattern=".*[^ ].*" 但由于某种原因它不适用于textarea。如果用户复制并粘贴 html 页面 ng 模式会引发错误。奇怪的是,当我将 textarea 更改为输入字段时,它工作正常。解决此问题的正确解决方案是什么。它允许用户粘贴某些内容,但是当我复制整个 html 页面并将其粘贴到 textarea 以进行测试时,我无法确定导致错误的原因。似乎中间的间距导致了它。 StackBlitz:https://stackblitz.com/edit/angular-nhvgf1?file=src/app/hero-form/hero-form.component.html

这是我粘贴在不应引发错误的文本区域中的内容:<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button> <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button> <i>with</i> reset

 <form (ngSubmit)="onSubmit()" #heroForm="ngForm">
  <div class="form-group">
    <label for="name">Name</label>
    <textarea type="text" class="form-control" id="name"
           required
            pattern=".*[^ ].*"
           [(ngModel)]="model.name" name="name"
           #name="ngModel"></textarea>
    <div [hidden]="name.valid || name.pristine"
         class="alert alert-danger">
      Name is required
    </div>
  </div>


  <button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
  <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
  <i>with</i> reset

  &nbsp;&nbsp;
  <button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>
  <i>without</i> reset

</form>

【问题讨论】:

  • 'required 效果很好,但如果用户单击空格按钮,表单会接受它。'你想保留这个空间吗?有时最好修剪()它,因为开始时的空格是无用的。
  • 只要该字段不为空。问题是空间,没有别的
  • 这似乎可以@AndrewAllen 运行一些测试,现在你介意解释一下。
  • 它在 stackblitz 中运行,但由于某些奇怪的原因,它冻结了我的本地应用程序
  • 你要求空,但有一个空间不是空的......同样,有时最好立即修剪起始空间,因为它没用。

标签: html angular validation templates


【解决方案1】:

您可以将此模式用于您的目的 "(\s*[^\s]+\s*)+"

【讨论】:

  • 当我将我的 html 页面复制到输入中时,它抛出了一个错误
  • 你知道如何使 ng-pattern 有条件,例如:pattern="condition ? '(\s*[^\s]+\s*)+' : ''"
【解决方案2】:

您可以创建一个自定义验证器和这种可重用的方法

export class StrictRequiredDirective  implements Validator {
  validator: ValidatorFn;

  constructor() {
    this.validate = this.isStrictRequired();
  }
  validate(c: FormControl) {
    return this.validate(c);
  }

  isStrictRequired() :ValidatorFn{
    return (c: AbstractControl) => {
      console.log(c.value)
      if (c.value && String(c.value).trim()) {
        return null
      } else {
        return {strictRequired : true}
      }
    }
  }

}

stackblitz demo ⚡⚡

【讨论】:

  • 谢谢,我试图避免制定自定义指令,因为这是一个小问题。我认为表单验证应该有一个更简单的解决方案。或者如果该字段为空,则可能是一个简单的抛出和错误函数
【解决方案3】:

尝试使用这种模式\S+.*

它允许用户使用空间但它是无效的(如果它只有空格):

在这种情况下,只有空格无效!

这个答案只是为了匹配您的初始请求,但我仍然认为为用户修剪它可以是更好的用户体验。

要使用修剪器指令,您可以使用:

import { ElementRef, HostListener } from '@angular/core';
import { Output, EventEmitter, Renderer2 } from '@angular/core';
import { Directive, Input } from '@angular/core';

@Directive({
  selector: '[forceTrim]'
})
export class TrimDirective {

  @Output() ngModelChange = new EventEmitter();
  constructor(
    private _renderer: Renderer2,
    private _elementRef: ElementRef) {
  }

  @HostListener("input", ["$event.target.value"])
  handleInput(inputValue: any): void {

      const valueToProcess = inputValue.trim();
      this._renderer.setProperty(this._elementRef.nativeElement, "value", valueToProcess);
      this.ngModelChange.emit(valueToProcess);

  }
}

在模板使用中:

    <input
      type="text"
      forceTrim
    />

【讨论】:

  • 在 stackblitz 中,我通过复制我的 html 页面对其进行了测试,结果它抛出并出错。最好走你建议的那条修剪路线
  • 试图避免使用自定义指令,但@az264 的回答效果很好,但我仍然投票,所以你可以打破 100 大声笑
【解决方案4】:

一个简单可靠的解决方案,就是将表单作为参数添加到 onSubmit,然后在 onSubmit 函数的开头进行额外检查。

HTML

<form (ngSubmit)="onSubmit(heroForm)" #heroForm="ngForm">
  <div class="form-group">
    <label for="name">Name</label>
    <textarea type="text" class="form-control" id="name"
           required
            pattern=".*[^ ].*"
           [(ngModel)]="model.name" name="name"
           #name="ngModel"></textarea>
    <div [hidden]="name.valid || name.pristine"
         class="alert alert-danger">
      Name is required
    </div>
  </div>


  <button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
  <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
  <i>with</i> reset

  &nbsp;&nbsp;
  <button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>
  <i>without</i> reset

</form>

类型脚本

import { NgForm } from '@angular/forms';

... 

onSubmit(theForm: NgForm) {
  if(theForm.controls.name.value.trim() == '') {handleErrors(theForm, 1); return;}
  ... the rest of your onSubmit Code.
}

handleErrors(theForm: NgForm, errorCode: number) {
  switch (errorCode) {
    case 1:
      console.log("Empty textarea.");
      theForm.controls.name.setError({Empty_Textarea: true});
    return;
    default:
      console.log("Unhandled error"); 
    return;
  }
}

【讨论】:

  • 谢谢,我会测试一下
  • 但是如何显示红色错误以便用户知道
  • @Flash 我已经修改了我的答案以包含错误处理程序。
猜你喜欢
  • 2021-03-30
  • 1970-01-01
  • 2017-01-30
  • 1970-01-01
  • 1970-01-01
  • 2019-01-20
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多