Angular 反应式 IP 地址验证器

Angular reactive form IP address validator

你好,我正在尝试对 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]?)')
      ])
    });

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

客户端验证:

  • 需要 was-validated class 在 <form> 标签上。

服务器端验证:

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

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

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

由于您还向 <form> 标签添加了 was-validated class,因此它按预期工作。

另一方面,您使用 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 class 到 form 标签,而是将所有当前控件设置为触摸。

例如

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

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

对于 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]?)')