javascript - Angular:呈现服务器端验证消息的正确方法

标签 javascript angular validation angular-forms

假设我在 Angular 中有这个表单:

<form [formGroup]="form">
    <md-input-container>
        <input mdInput formControlName="name" [(ngModel)]="dummy.name" name="name">
        <md-error *ngIf="form.controls.name.hasError('required')">This is required</md-error>
    </md-input-container>
    <md-input-container>
        <input mdInput formControlName="email" [(ngModel)]="dummy.email" name="email">
        <md-error *ngIf="form.controls.email.hasError('invalid_format')">The email is not valid</md-error>
    </md-input-container>
</form>

提交给网络服务进行保存、更新等。网络服务当然必须检查输入是否正确,并返回一些验证消息以防出现任何问题。假设我 POST 表单并在 JSON 字典中得到这些验证错误:

{
    "name": [
        "Middle names are not allowed."
    ],
    "email": [
        "The email already exists."
    ]
}

我不清楚 Angular 应该如何处理这种情况。周围的大多数信息都建议编写一个自定义验证器,该验证器将对服务器进行异步验证,例如:

uniqueEmailValidator(control: Control): {[key: string]: any} {
    return new Promise (resolve => {
        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        this.http.get('http://webservice.com/email/unique/', {headers:headers})
            .map(res => res.json())
            .subscribe(data => {
                if(data != null) {
                    resolve({"duplicate": true})
                }
                else resolve(null);      
            })
        });
    });
}

现在,这意味着我应该为我的表单中可能存在的每个数据片段提供一个特定的 Web 服务。虽然这在某些特定情况下可能有意义(例如唯一的电子邮件/用户名验证),但我不喜欢用大量仅执行验证任务的服务填充我的 Web API,然后不得不在我的代码中编写验证器的想法 Angular 项目。

我想到的一个可能的解决方案是将服务器错误对象作为属性保存在我的组件中,然后使用 Angular 验证器检查特定字段是否有错误消息:

public checkServerErrorMessage(control: FormControl):{[key: string]: boolean}{
    if("name" in this.serverErrors){
        return { serverValidationError: true };
    }
    return {};
}

然后使用 updateValueAndValidity 或某种东西强制验证器刷新。但我觉得这不对。是否有解决这种情况的“Angular ”方法?

最佳答案

因为我得到了一些赞成票,以防万一有人遇到这个问题,这里是我制定的解决方案。

我没有使用验证器,而是使用 setError 方法在控件上手动触发验证错误(在我的理解中,这基本上是验证器会做的)。

因此,在我的组件中,我将遍历服务器的响应以确定每个字段是否有错误。我想您可以通过多种方式确定这一点,这取决于您的 Web 服务的设计方式。在我的例子中,如果控件的名称出现在服务器返回的错误字典中,则会出现错误。如果是这样,我将匹配的表单控件标记为“serverValidationError”(或者你想怎么调用它):

for(var key in serverResponse["errors"]) { 

    this.serverErrors[key] = serverResponse["errors"][key]
    this.form.controls[key].setErrors({serverValidationError: true});

}

“serverErrors”将存储来自服务器的消息以在模板上显示它们。

然后在模板中,我检查该错误:

<form [formGroup]="form">
    <md-input-container>
        <input mdInput formControlName="name" [(ngModel)]="dummy.name" name="name">
        <md-error *ngIf="form.controls.name.hasError('serverValidationError')">{{ serverErrors["name"] }}</md-error>
    </md-input-container>
    <md-input-container>
        <input mdInput formControlName="email" [(ngModel)]="dummy.email" name="email">
        <md-error *ngIf="form.controls.email.hasError('serverValidationError')">{{ serverErrors["email"] }}</md-error>
    </md-input-container>
</form>

不知道这是否是最好的解决方案,但至少是我能想到的最好的。

PS:我是凭内存写的,所以代码可能不是 100% 正确。

关于javascript - Angular:呈现服务器端验证消息的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45585831/

相关文章:

javascript - 如何在 moment.js 中比较两个日期

angular - 将 Angular2 react 形式与嵌套的 TypeScript 模型对象一起使用

angular - 创建一个可以在 Angular 4 模板中使用的全局函数

angular - 自定义比较密码验证器和这个 [Angular 2,4,5,6]

ruby-on-rails - 如何使 simple_form 与 twitter-bootstrap-rails 一起工作; Bootstrap 中的一般形式

java - @Email 验证注释导致部署中出现 NullPointerException

javascript - JavaScript 中的 ":"运算符

javascript - React JS - 未捕获的类型错误 : props. video.map 不是函数

ruby-on-rails - Ruby float 学 - Sum Calc 中的精度问题

javascript - 本地 Node 项目的全局安装是否只创建返回到该项目的可执行链接?