我用过p-toast的一个messagBox。当我单击删除时,我想输入是或否值,然后它将按api键删除该项目。不,它不会做任何事情。这件事正在工作,但是当我单击第一个项目时,我单击否,然后我单击第二个项目,然后在消息框中单击“是”,此后它将删除第一和第二个项目。我首先要删除当前项目。
messagebox.service.ts:
public messageSource = new BehaviorSubject(false); currentMessage =
this.messageSource.asObservable();
public _msgBoxSubject: EventEmitter<boolean> = new
EventEmitter<boolean>(); public confirmResponse: boolean = false;
response: boolean = false;
show() {
this.messageSource.next(false);
this.response = true;
this._msgBoxSubject.emit(this.response); }
onYes(value) {
this.messageSource.next(value);
this.confirmResponse = value; }
onNo(value1) {
this.confirmResponse = value1; }
hide() {
this.response = false;
this._msgBoxSubject.emit(this.response); }
getMsgBoxEmitter() {
return this._msgBoxSubject; }
messagebox.component.ts:
ngOnInit() {
this._msgBoxService.getMsgBoxEmitter().subscribe((value: boolean) => {
this.messageService.clear();
this.messageService.add({ key: 'c', sticky: true, severity: 'warn', summary: 'Are you sure?', detail: 'Confirm to proceed' });
}); }
onConfirm() {
this.messageService.clear('c');
this._msgBoxService.onYes(true); }
onReject() {
this.messageService.clear('c'); }
emailmaster.component.ts: (我在单击删除按钮时调用此功能)
deleteEmail(ID: Email) {
this._msgBoxService.show();
this._msgBoxService.currentMessage.subscribe(response1 => {
if (response1 === true) {
this._masterservice.deleteEmail(ID).subscribe(data => {
this._toasterService.showMessage('Email deleted successfully', 'Success Message', 'success');
if (data) {
this.GetEmails();
}
});
}
});
}
我只希望在单击消息框的“是”时删除当前项目。
答案 0 :(得分:1)
您的deleteEmail
方法并未取消订阅currentMessage
的Observable。尝试如下操作:
deleteEmail(ID: Email) {
this._msgBoxService.show();
this._msgBoxService.currentMessage.pipe(
filter(response1 => response1), // only allows true values through
take(1), // takes one emission per subscription and then completes
mergeMap(() => this._masterservice.deleteEmail(ID)), // mergeMap can be used safely because you're only getting one emission
tap(() => this._toasterService.showMessage('Email deleted successfully', 'Success Message', 'success')),
filter(data => !!data), // only emissions where data exists here will continue
tap(() => this.GetEmails())
).subscribe();
}
我还建议您添加错误处理,因为如果此处出现任何故障,您将不会发现它。例如,您可以添加一个catchError
块。
答案 1 :(得分:1)
因此,正如另一个答案所建议的那样,我认为问题是,您从未取消对currentMessage的deleteEmail函数中的订阅,因此它是基于先前的尝试
deleteEmail(ID: Email) {
this._msgBoxService.show();
this._msgBoxService.currentMessage.subscribe(response1 => {
if (response1 === true) {
this._masterservice.deleteEmail(ID).subscribe(data => {
this._toasterService.showMessage('Email deleted successfully', 'Success Message', 'success');
if (data) {
this.GetEmails();
}
});
}
});
}
当前流量示例。
您对deleteEmail的呼叫会弹出一个确认,并且您的代码订阅了答案,并寻找了答案。
您单击否(否),确认消失,但订阅仍在继续收听。
您的下一个删除电子邮件的呼叫弹出一个确认,您的代码再次订阅答案,现在有两个订阅正在侦听。
您单击“是”(true),这两个订阅都将跳入操作,发送对第一项和第二项的删除请求。
另一位发贴人的想法是正确的,但他们的方法行不通,因为只有当事情是真的时,您的服务才会发出。它永远不会说什么时候是假的。因此,尝试take(1)意味着它将就坐在那儿,直到有人说是。
所以我们需要做一些小改动才能使它工作。
this._msgBoxService.currentMessage
.pipe(take(1)) // this completes the observable after hearing 1 value from it
.subscribe(response1 => {
onReject() {
this.messageService.clear('c');
this._msgBoxService.onNo(false); // send the onNo when rejected
onNo(value1) {
this.messageSource.next(value1); // when onNo called, emit the value so old subscribers can complete
this.confirmResponse = value1; }
show() {
// this.messageSource.next(false); // remove this line to avoid hearing it's emit
this.response = true;