【问题标题】:Angular - Refresh/Get data after deleteAngular - 删除后刷新/获取数据
【发布时间】:2019-02-19 17:44:25
【问题描述】:

我在对 Angular 了解不多的情况下使用 Angular 完成了一个正在运行的项目。我目前正在开发一个简单的 CRUD 屏幕。删除一行后,我该如何“刷新” UI?以下是我的组件中的方法:

    AATList:IAat[];

confirmDelete(): void{
    //this.myService.deleteAAT(this.satNumber).subscribe(data => {this.AATList = data;});
    //this.myService.deleteAAT(this.satNumber).subscribe(() => {this.getAATtEntries(); });
    this.myService.deleteAAT(this.satNumber).subscribe();
    this.getAatEntries();
    this.modalRef.hide();
}

getAATtEntries() {
    console.log("entries");
    this.myService.getAATList().subscribe(data => {this.AATList = data});
}

(在编辑时添加,在组件内部):

openDeleteModal(template: TemplateRef<any>, satNumber: number) {
    this.satNumber = satNumber;
    this.modalRef = this.modalService.show(template, {class: 'modal-sm'});
  }

服务:

getAATList() {
    return this.httpClient.get<ISmt[]>(environment.ApiEndPoint + '/api/SMTDatas', {withCredentials:true});
}

deleteAAT(satNumber : number) {
    return this.httpClient.delete(environment.ApiEndPoint + '/api/SMTDatas/' + satNumber, {withCredentials:true} )
}

(我使用来自@angular/common/httpHttpClient 来提供服务)

我已经尝试了 confirmDelete 方法的前三行,但没有成功。我在这里想念什么?我对 Angular 的掌握不是很好,所以请随时指出其他任何内容。

更新: HTML:

    <a class="text-danger" data-toggle="tooltip" data-placement="top" title="Delete" (click)="openDeleteModal(deleteTemplate, smt.SMTNumber)"><i class="fa fa-trash"></i>Delete</a>
...
    <ng-template #deleteTemplate>
      <div class="modal-body text-center">
        <p>Are you sure you want to delete this SAT?</p>
        <button type="button" class="btn btn-default" (click)="confirmDelete()" >Yes</button>
        <button type="button" class="btn btn-primary" (click)="denyDelete()" >No</button>
      </div>
    </ng-template>

【问题讨论】:

  • 我想你可以订阅 modelRef.hide 方法。您可以尝试一下并在订阅时调用 get 方法。像 this.modelRef.hide().subscribe(result=>{this.getAATtentries();});
  • getAATList 返回ISmt 的列表并将其分配给getAATtEntries 中的IAat 列表,它们是否具有相同的字段?
  • @ZearaeZ 看来我做不到。 “void”类型上不存在属性“subscribe”
  • @WaelAbbas 是的,他们确实有相同的字段
  • @ZearaeZ 您正在使用哪个模态modalRef 组件?

标签: angular typescript get


【解决方案1】:

注意:出于责任感,我在帖子下方添加了更新信息,以提供稍微“更好”的见解


TL;DR:阅读订阅和主题,以及如何在组件和服务之间建立通信。您可以通过在成功发出 DELETE 请求后发出 GET 请求或在发出成功的 DELETE 请求后通过从列表中本地删除项目来更新 UI 来实现您想要的。

加长版:

一个想法可以如下:

如果您做出希望稍后能够看到的更改(例如 99.9% 的应用),您将需要进行后端调用。

您如何更新您的 UI 取决于您希望如何继续它,在您进行后端调用之后

因此考虑一个从列表中删除项目的情况。您为该特定项目发送删除请求,并从后端接收响应。此响应应该告诉您您所做的删除操作是否成功。

根据这些信息,您可以

1) 通过迭代找到列表中的项目并在本地删除它(更快)

2) 向后端发出另一个 GET 请求,并在您成功删除后显示新更新的结果(更安全,但您最终会为每个操作发出 2 个请求)。

如何解决“删除是否成功”问题取决于您的实施,但我将在下面分享一个。

为此,使用 rxjs 了解 SubscriptionsSubjects 会对您有所帮助。我会按照上面提到的第二个选项来写。

在您拨打电话的服务上,您可以创建主题。您将使用此主题通过 next 方法通知侦听器(即订阅此事件的任何人)任何更新。

在您的服务中,您可以按如下方式创建新的主题:

private _deleteOperationSuccessfulEvent$: Subject<boolean> = new Subject();

并为它创建一个getter,如下所示:

get deleteOperationSuccessfulEvent$(): Observable<boolean> {
    return this._deleteOperationSuccessfulEvent$.asObservable();
} 

当您收到 HTTP DELETE 请求的响应时,根据成功或失败,您可以发出一个真或假值,如下所示:

this._deleteOperationSuccessfulEvent$.next(true);

到目前为止,我们正在发出删除操作是否成功的信息。

但还没有人在听。所以在你的组件中,你可以创建一个订阅:

deleteOperationSuccessfulSubscription: Subscription;

在您的 ngOnInit 方法中,您可以订阅在您的服务中创建的 deleteOperationSuccessfulEvent$:

this.deleteOperationSuccessfulSubscription = this.yourService.deleteOperationSuccessfulEvent$.subscribe(...stuff will come here...);

(请注意,我们使用了 deleteOperationSuccessfulEvent$ 值,而不是私有 _deleteOperationSuccessfulEvent$。)

现在您的组件正在侦听您的服务的 delete.. 事件。我们只需要采取行动。

this.deleteOperationSuccessfulSubscription = this.yourService.deleteOperationSuccessfulEvent$
    .subscribe(isSuccessful => {
        if (isSuccessful === true) { 
            make a GET request and display the returning data, following similar steps to which we followed so far 
        } else {
            delete operation was NOT successful, you can display an error or retry etc.
        }
    });

如果您有任何问题,请告诉我。


更新:在进行所有这些操作时,从 Angular 和 rxjs 的角度来看,应该注意一些事项:

1- 尽量不要在打字稿代码中使用.subscribe() - 而是尝试使用.pipe() 运算符来处理您的逻辑。相反,让 Angular 在你的模板中使用 async pipe 来处理你的订阅。 您可以在.pipe() 中添加.catchError(err =&gt; ...),以确保您发现错误并正确处理它们。

2- 如果您确实必须使用.subscribe(),请不要忘记在ngOnDestroy() {...} 中取消订阅该订阅。否则,您的应用程序将面临内存泄漏的风险。

ngOnDestroy() {
  this.mySubscription.unsubscribe();
} 

【讨论】:

  • 这是最好的方法,如果服务器对删除的响应成功并且其余数据没有发生变化,那么只需将其从填充在前面的数组中删除结尾。没有理由再使用服务器资源了。
  • 这对我决定是删除该项目还是重新加载整个列表有很大帮助。
【解决方案2】:

编辑:我认为您在执行请求之前关闭了模式。还假设您想在 parent 中获取列表,而不是在模式中。所以首先我会删除,隐藏模态,收听在父级中关闭的模态,然后重新获取列表......就像这样:

this.myService.deleteAAT(this.satNumber).subscribe(() => this.modalRef.hide());

然后在你的父母中,听隐藏:

this.modalService.onHide.pipe(
  switchMap(() => this.myService.getAATList())
).subscribe(data => {this.AATList = data})

原文:

当你这样做时:

this.myService.deleteAAT(this.satNumber).subscribe();
this.getAatEntries();

getAatEntries() 实际上是在删除完成之前触发的(很可能),因此您需要链接这些请求,您可以使用 switchMap 实现此目的:

this.myService.deleteAAT(this.satNumber).pipe(
  switchMap(() => this.myService.getAATList())
)
.subscribe((data: ISmt[]) => this.AATList = data);

【讨论】:

  • 哦,等等,我没有看到注释掉的代码,this.myService.deleteAAT(this.satNumber).subscribe(() =&gt; {this.getAATtEntries(); }); 应该可以工作,但不建议在订阅内订阅。您是否收到任何错误,这两个请求是否都正确触发并且没有抛出错误?
  • 感谢您的回复。看来 Get 没有在 Delete 订阅中触发。没有错误被抛出。如果我导航到页面上的另一个链接或刷新页面,则该行不再可见,也不会引发错误。您还需要从代码中看到什么吗?此外,我必须通过在 switchMap 内围绕返回值添加括号来调整代码 sn-p,但结果相同,Get 没有在 Delete 中触发。有什么想法吗?
  • 编辑了我的答案,我现在做了很多猜测,所以这可能不正确,如果没有帮助,请创建minimal reproducible example(基本上应该总是这样做;))否则无法提供帮助。
  • 我会试试的,我知道。我认为这对我来说可能是愚蠢的,或者我很幸运能得到其中一个答案:)
  • 在我手动单击模式后,这似乎已删除并刷新了 UI。我添加了额外的代码,看看是否可以清除任何东西。谢谢你的时间。
【解决方案3】:

您可以使用模型的onHidden 事件(当模式对用户隐藏完毕时触发)来加载您的数据,如下所示。

constructor(private modalService: BsModalService) {
    this.modalService.onHidden.subscribe(() => {
         // Fired when the modal has finished being hidden from the user
        this.getAATtEntries();
    });
}

confirmDelete(): void{
    this.myService.deleteAAT(this.satNumber).subscribe(() => { this.modalRef.hide(); });
}

【讨论】:

  • 这可行(在一定程度上),但我必须单击模式才能隐藏和刷新模式。是否还有其他可能影响隐藏操作的因素?
  • @user94614 没有明白你的意思,你能描述更多关于什么不起作用吗?
  • 抱歉,当我在模态框上单击“是”时,会触发删除操作,但在我单击模态框外部(屏幕上的其他位置)之前,get 和模态不会隐藏。如果可以澄清任何事情,我确实进行了编辑。
  • @user94614 你在哪里打电话给this.modalRef.hide();
  • @user94614 尝试在this.modalRef.hide();之前添加this.modalService.setDismissReason('Yes');
猜你喜欢
  • 2017-05-22
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 2015-10-03
  • 2012-08-03
相关资源
最近更新 更多