【问题标题】:Angular reactive form IP address validatorAngular 反应形式 IP 地址验证器
【发布时间】:2021-09-08 18:18:21
【问题描述】:

您好,我正在尝试对 Angular 中的 IP 地址使用验证器。然而,似乎即使我输入了一个无效的 IP 地址,即12.2.2.2...,GUI 显示它是有效的(见图)。但是,控制台日志显示它是模式不匹配(这意味着它检测到不正确的模式)。我不确定我错过了什么。现在开始感到困惑。需要一双新的眼睛来发现缺陷。

请注意,所需部分已经在使用ipaddress。我只是对它为什么不能进行模式验证感到困惑。看图

见我的stackblitz

这是我的代码

HTML

<div class="form-group row required" [ngClass]="{
  'is-invalid': ipaddress.invalid && (ipaddress.dirty || ipaddress.touched),
  'is-valid': ipaddress.valid && (ipaddress.dirty || ipaddress.touched)
}">
  <label for="ipaddress" class="col-sm-3 col-form-label">IP Address</label>
  <div class="col-sm-7">
    <input type="text" class="form-control" placeholder="IP Address"
        id="ipaddress" name="ipaddress" formControlName="ipaddress"
        ngbAutofocus required>
    <div class="form-control-feedback invalid-feedback"
        *ngIf="ipaddress.errors">
      <p *ngIf="ipaddress.errors.required">IP Address is required</p>
      <p *ngIf="ipaddress.errors.pattern">Invalid IP Address format</p>
    </div>
  </div>
</div>

TS 文件

  this.ipaddress = new FormControl('', {
      validators: Validators.compose([
        Validators.required,
        Validators.pattern('(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)')
      ])
    });

【问题讨论】:

  • 你能创建 stackblitz 吗?
  • 我不会创建自己的正则表达式,而是使用使用npmjs.com/package/is-ip的自定义验证器
  • @Chellappanவ 添加了我的堆栈闪电战
  • 期望当IP地址无效时,输入字段应该是红色而不是带有复选标记,当前,它在输入字段上显示绿色并带有复选标记

标签: angular typescript angular-reactive-forms angular-forms


【解决方案1】:

我认为你有这种不一致是因为你混合了Bootstrap understands 的两种类型的验证:

客户端验证:

  • 需要&lt;form&gt; 标记上的was-validated 类。

服务器端验证:

  • 标签上不需要was-validated 类。
  • 需要输入控件上的.is-valid.is-invalid 类。

您的 IP 地址输入控件上有 required 属性。此属性允许浏览器应用本机内置表单验证,这意味着如果该控件无效,则它匹配:invalid CSS 伪类。 Bootstrap 框架为此行为提供了专门的类:

.was-validated .form-control:invalid {
  border-color: <red>;
  ...

由于您还将 was-validated 类添加到 &lt;form&gt; 标记,因此它可以按预期工作。

另一方面,您使用 Angular 验证模式:

this.ipaddress = new FormControl('', [
  Validators.required,
  Validators.pattern("....")
]);

它不会应用内置浏览器验证,您必须手动设置.is-valid.is-invalid。但是您只能对 Bootstrap 使用一种类型的验证

所以,这里有你的选择:

  1. 仅使用客户端验证:

html

<input type="ipaddress"
    class="form-control"
    formControlName="ipaddress"
    required
    pattern="^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$">

Stackblitz Example

  1. 使用 Bootstrap 服务器端验证逻辑。

这样做

  • 您需要删除将was-validated 类添加到form 标记,而是将所有当前控件设置为已触摸。

例如

this.myform.markAllAsTouched();
  • 移动添加 .is-valid.is-invalid 类以控制自身而不是其包装器

html

<input type="ipaddress"
    class="form-control"
    formControlName="ipaddress"
    [ngClass]="{
  'is-invalid': ipaddress.invalid && (ipaddress.dirty || ipaddress.touched),
  'is-valid': ipaddress.valid && (ipaddress.dirty || ipaddress.touched)
}">

Stackblitz Example

【讨论】:

  • 哦,我只是确认一下,角度验证器部分需要pattern 属性吗?还是基本上依赖属性?尽管我正在混合验证(客户端到服务器端),但这对我来说确实很有意义,感谢您清理一切
  • Angular 有内置的 PatternValidator 指令github.com/angular/angular/blob/… 这意味着你可以在代码中应用验证器或使用属性
【解决方案2】:

对于 js & ts 你可以使用以下:

Validators.pattern('(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-21
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多