繁体   English   中英

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

[英]Angular: Correct approach for rendering server side validation messages

假设我在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>

提交给Web服务进行保存,更新等。当然,Web服务必须检查输入是否正确,并在出现任何问题时返回一些验证消息。 假设我在表单中发布并在JSON字典中获取这些验证错误:

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

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

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验证器来检查特定字段是否有错误消息:

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

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

因为我已经获得了一些赞成,并且万一有人正在努力解决这个问题,这就是我编写的解决方案。

我没有使用验证器,而是最终使用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%正确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM