Angular 乐观锁定:保存一个数据的多个请求
正如你在这个例子中看到的。当输入文本的焦点丢失时,它应该导致http请求保存当前数据。当点击复选框时,它也应该保存数据。在这种情况下,它存在以下问题:Angular 乐观锁定:保存一个数据的多个请求,angular,database,optimistic-locking,Angular,Database,Optimistic Locking,正如你在这个例子中看到的。当输入文本的焦点丢失时,它应该导致http请求保存当前数据。当点击复选框时,它也应该保存数据。在这种情况下,它存在以下问题: 焦点丢失在复选框上 编辑名称时,只需单击复选框。它将导致两个事件:焦点丢失和单击。 焦点丢失首先发生,它将调用onBlur()函数,然后单击事件将发生,并调用handleClick()函数 但是在onBlur()函数中,它有http请求。所以应该是这样的:clint没有得到http响应,但是handleClick()再次向restfulapi
- 焦点丢失在复选框上
onBlur()
函数,然后单击事件将发生,并调用handleClick()
函数
但是在onBlur()
函数中,它有http请求。所以应该是这样的:clint没有得到http响应,但是handleClick()
再次向restfulapi发送相同数据的另一个http请求。数据库具有乐观锁,这将导致第二个请求失败
而且,如果数据只是一个新对象,它还没有保存到数据库中,那么它的id为null。当焦点丢失时,它应该导致http POST,然后客户端得到http响应,数据得到ID。实际上客户端不会等待得到http响应,只需调用handleClick()
函数,数据仍然没有ID,它将导致同一数据上的另一个http POST
有没有更好的办法来解决这个问题?请提供帮助。在这种情况下,您可以将rxjs与
去BounceTime
结合使用:
export class AppComponent implements OnInit {
data: MyObject;
private saveData$ = new Subject<void>();
private destroy$ = new Subject<void>();
ngOnInit() {
// in real situation, data should come from restful api, or just a new objecy.
this.data = {
name: 'qqq',
aa: false,
bb: true
};
this.saveData$.pipe(
debounceTime(100),
takeUntil(this.destroy$);
).subscribe(() => {
// http POST or PUT
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
handleClick() {
this.saveData$.next();
}
onBlur() {
this.saveData$.next();
}
}
导出类AppComponent实现OnInit{
资料:MyObject;
私有存储数据$=新主题();
private destroy$=新主题();
恩戈尼尼特(){
//在实际情况中,数据应该来自RESTfulAPI,或者只是一个新对象。
此参数。数据={
名称:“qqq”,
aa:错,
是的
};
此.saveData$.pipe(
去BounceTime(100),
takeUntil(这个.destroy$);
).订阅(()=>{
//http POST或PUT
});
}
ngOnDestroy():void{
this.destroy$.next();
此.destroy$.complete();
}
handleClick(){
此.saveData$.next();
}
onBlur(){
此.saveData$.next();
}
}
您可以在代码中使用“提交”标志。这样,您在任何情况下都不会多次提交表格。此外,您还可以使用相同的标志来禁用“提交”按钮。检查我根据您的代码制作的Stackblitz示例:
要点是提交方法:
submit() {
if (this.submitting) {
return;
}
this.submitting = true;
console.log("submitting: ", this.submitting);
const data = {};
this.http.post("http://yourapi.com", data).subscribe(res => {
this.submitting = false;
},
err => {
console.log(err);
setTimeout(() => {
this.submitting = false;
}, 3000);
}
)
}
在这种情况下,更好的方法可能是使用submit按钮对所有表单数据进行一次调用。忘了在示例中提到,当您单击按钮或触发onBlur事件时,您可以看到在这两种情况下如何禁用submit按钮。我尝试过,如果有多个数据,则使用bufferTime可能更好。
export class AppComponent implements OnInit {
data: MyObject;
private saveData$ = new Subject<void>();
private destroy$ = new Subject<void>();
ngOnInit() {
// in real situation, data should come from restful api, or just a new objecy.
this.data = {
name: 'qqq',
aa: false,
bb: true
};
this.saveData$.pipe(
debounceTime(100),
takeUntil(this.destroy$);
).subscribe(() => {
// http POST or PUT
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
handleClick() {
this.saveData$.next();
}
onBlur() {
this.saveData$.next();
}
}
submit() {
if (this.submitting) {
return;
}
this.submitting = true;
console.log("submitting: ", this.submitting);
const data = {};
this.http.post("http://yourapi.com", data).subscribe(res => {
this.submitting = false;
},
err => {
console.log(err);
setTimeout(() => {
this.submitting = false;
}, 3000);
}
)
}