使用模式 Angular 2 进行输入验证

Input validation with pattern Angular 2

我目前正在用 ionic 2 (Angular 2) 编写一个简单的表格。我想知道如何将简单的 regular expression 模式添加到验证中:

我基本上有这个:

<form>
    <ion-input stacked-label>
        <ion-label>{{label.msisdn}}</ion-label>
        <input type="text"
               [(ngModel)]="msisdn"
               ngControl="msisdnForm"
               required
               maxlength="10"
               minlength="10"
               pattern="06([0-9]{8})"
               #msisdnForm="ngForm"
        >
    </ion-input>
    <button [disabled]="!msisdnForm.valid" block (click)="requestActivationCode()">
        {{label.requestActivationCode}}
    </button>
</form>

正在选取最大长度、最小长度和所需的长度(如果不满足条件,该按钮将被禁用)。现在我想将输入限制为数字,并在其前面加上 06(荷兰语 phone 数字最少)。

然而,验证中未选取该模式。我可以这样做吗,还是需要代码方法?

将模式添加到变量

var pattern=/06([0-9]{8})/;

并将属性绑定到它

 <input type="text"
               [(ngModel)]="msisdn"
               ngControl="msisdnForm"
               required
               maxlength="10"
               minlength="10"
               [pattern]="pattern"
               #msisdnForm="ngForm"
        >

看来这个 PR https://github.com/angular/angular/pull/6623/files 需要先落地。

还有一个未解决的问题https://github.com/angular/angular/issues/7595 这可以防止 pattern 被绑定。该模式需要静态添加到 DOM(无绑定)才能工作。

我提供了更多详细信息(Angular 2.0.8 - 2016 年 3 月 3 日): https://github.com/angular/angular/commit/38cb526

回购示例:

<input [ngControl]="fullName" pattern="[a-zA-Z ]*">

我测试了它,它起作用了:) - 这是我的代码:

<form (ngSubmit)="onSubmit(room)" #roomForm='ngForm'  >
...
<input
  id='room-capacity'
  type="text"
  class="form-control"
  [(ngModel)]='room.capacity'
  ngControl="capacity"
  required
  pattern="[0-9]+"
  #capacity='ngForm'>

2017 年 9 月更新

我只想说,目前当我有更多经验时,我通常使用以下'cheap'方法来验证数据:

验证仅在服务器端进行(根本不在 angular 中!),如果出现问题,则服务器 (Restful API) return 一些错误代码例如 HTTP 400 和响应主体中的以下 json 对象(在 angular 中我放入 err 变量):

this.err = { 
    "capacity" : "too_small"
    "filed_name" : "error_name", 
    "field2_name" : "other_error_name",
    ... 
}

(如果服务器 return 格式不同的验证错误,那么您通常可以轻松地将其映射到上述结构)

在 html 模板中,我使用单独的标签(div/span/small 等)

<input [(ngModel)]='room.capacity' ...>
<small *ngIf="err.capacity" ...>{{ translate(err.capacity) }}</small>

如您所见,当 'capacity' 中出现错误时,带有错误翻译(用户语言)的标签将可见。这种方法有以下优点:

  • 很简单
  • 在 angular 中,我们不会双重验证代码(并且必须是)在服务器中(在正则表达式验证的情况下,这可以防止或复杂化 ReDoS 攻击)
  • 我们可以完全控制向用户显示错误的方式(这里是 <small> 标签中的示例)
  • 因为在服务器响应中我们 return error_name (而不是直接的错误消息),我们可以很容易地更改错误消息(或翻译它)仅修改 frontend-angular 代码(或带有翻译的文件)。所以在那种情况下我们不需要触摸 backend/server 代码。

当然有时(如果需要 - 例如,永远不会发送到服务器的 retypePassword 字段)我对上述方法进行了例外处理并在 angular 中进行了一些验证(但使用类似的“this.err”机制来显示错误(所以我不直接在 input 标签中使用 pattern 属性,而是在用户引发适当的事件(如输入更改或保存)后,我在某些组件方法中进行正则表达式验证)。