文章内容

2021/12/24 15:24:01,作 者: 黄兵

Angular 表单输入判断输入是否已存在于数据库


我们在开发 Angular 后台管理系统的时候,经常可以遇到数据模型的约束类型为唯一,这个时候我们就需要对输入的内容进行查询,看看是否存在于数据库。

下面是模型的相关代码:

# UserAgent处理结果
class ProcessUserAgent(db.Model):
__tablename__ = 'user_agent_process'
id = db.Column(db.Integer, primary_key=True)
user_agent = db.Column(db.String(1024), index=True, unique=True)
bot = db.Column(db.Boolean)
touch_capable = db.Column(db.Boolean, doc='可触摸设备')
browser_id = db.Column(db.SmallInteger, db.ForeignKey('browser.id'))
os_id = db.Column(db.Integer, db.ForeignKey('operating_systems.id'))
device_id = db.Column(db.SmallInteger, db.ForeignKey('devices.id'))
device_brand_id = db.Column(db.SmallInteger, db.ForeignKey('device_brands.id'))
confirm = db.Column(db.Boolean, doc='人工确认')
create_time = db.Column(db.DateTime(timezone=True), server_default=func.now(), index=True)
time_updated = db.Column(db.DateTime(timezone=True), onupdate=func.now())

上面 user-agent 字段是唯一约束,需要在表单中检查输入是否存在于数据库。

后端检查代码:

if request.method == 'GET':
get_user_agent = request.args.get('UserAgent')
if get_user_agent:
user_agent_exits = ProcessUserAgent.query.filter_by(user_agent=get_user_agent).first()
if user_agent_exits:
return jsonify(True)
else:
return jsonify(False)

获取 url 中 UserAgent 的参数,查询数据库,存在返回 True,反之。

前端代码服务代码如下:

public validateUserAgentInput(userAgent: string): Observable<boolean> {
return this.http.get<boolean>(`${this.requestUserAgentUrl}/process?UserAgent=${userAgent}`, {
headers: new HttpHeaders().set('Authorization', this.auth.accessToken)
});
}

提交数据,到后端查询是否存在。

对输入处理的相关代码如下:

validateUserAgentExits(ctrl: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
return this.crawlerService.validateUserAgentInput(ctrl.value).pipe(
map(isTaken => (isTaken ? {uniqueUserAgent: true} : null)),
catchError(() => of(null)));
}

以上代码主要是 RxJS 的操作符。

之后表单具体代码如下:

<div class="form-group row">
<mat-form-field appearance="fill" class="col-lg-12">
<mat-label>User-agent</mat-label>
<input matInput [formControl]="userAgentFormControl" placeholder="例如:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" maxlength="1024" required>
<mat-hint align="end">{{userAgentFormControl.value?.length || 0}}/1024</mat-hint>
<mat-hint align="start" *ngIf="userAgentFormControl.pending">正在验证 User-agent 是否已存在...</mat-hint>
<mat-error *ngIf="userAgentFormControl.invalid">
<div *ngIf="userAgentFormControl.hasError('required')">
<mat-icon>info</mat-icon>请输入 User-agent
</div>
<div *ngIf="userAgentFormControl.errors?.uniqueUserAgent">
<mat-icon>info</mat-icon>User-agent 已存在,请检查!
</div>
</mat-error>
</mat-form-field>
</div>

通过以上操作,就可以对用户的输入进行验证,查询是否存在于数据库。

最后我们看一下效果:


当 User-agent 为空,提示请输入 User-agnet ,当 User-agent 已存在于数据库,提示已存在。


如果我们在编辑的时候,复用的是同一个页面,如果还存在验证,会导致无法保存的问题,因为上面的表单无法通过前端验证,这个时候我们就需要使用这个  clearAsyncValidators() 功能。

clearAsyncValidators() 主要是清空了异步验证其的控制列表。

updateValueAndValidity() 主要是为了重新计算控件的值和验证状态。

最后在编辑页面重设验证的完整代码如下:

getTagById(id: number) {
this.loading = true;
this.sub = this.ipCrawlerService.getTagById(id).subscribe(res => {
this.tagFormControl.setValue(res.tag);
this.tagFormControl.clearAsyncValidators();
this.tagFormControl.updateValueAndValidity();
this.linkTextFormControl.setValue(res.linkText);
this.linkTextFormControl.clearAsyncValidators();
this.linkTextFormControl.updateValueAndValidity();
}, error => {
this.snackBar.open(error.error.message ?? error.message, '关 闭', {
horizontalPosition: 'start',
verticalPosition: 'bottom',
duration: 3000,
});
}, () => {
this.loading = false;
});
}


参考资料:

1、Angular Doc - setAsyncValidators()

2、Angular FormControl Add and Remove Validators Dynamically


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - Angular 表单输入判断输入是否已存在于数据库

收集整理 UA
SEO 测试
分享到:

发表评论

评论列表