如何在不订阅 Angular 表单提交的情况下创建/更新项目
Posted
技术标签:
【中文标题】如何在不订阅 Angular 表单提交的情况下创建/更新项目【英文标题】:How to Create/Update item without subscribe on form submit with Angular 【发布时间】:2019-08-05 16:49:54 【问题描述】:在我的 Angular 7 应用程序中,我结合了一些众所周知的良好实践和模式。有些是 OnPush 更改检测,takeUntil 模式 来取消订阅 Observables,我尝试尽可能多地使用 Async Pipe,因此 Angular 会处理大多数情况的东西。
所以我的组件通常是这样的:
在 my.component.ts
中data$: Observable<MyObject>;
ngOnInit()
this.data$ = this.myService.loadData().pipe(shareReplay());
在模板中:
<ng-template #myLoader>Loading...</ng-template>
<div *ngIf="(data$ | async) as data; else myLoader">
data.label
</div>
所以我不需要为 takeUntil 模式添加单独的 Subject。但是,如果我有一个编辑/更新表单并且我加载数据来填写表单。然后我需要将输入的数据保存在表单提交中,然后再次进行 HTTP 调用。成功后,我需要重定向页面,所以通常我所做的就是订阅 observable 并在那里重定向。因此,如果我要订阅,我需要取消订阅,然后我会再次返回 takeUntil:
private unsubscribe$: Subject<any> = new Subject<any>();
ngOnDestroy(): void
this.unsubscribe$.next(null);
this.unsubscribe$.unsubscribe();
submit(value)
this.myService
.update(value)
.pipe(takeUntil(this.unsubscribe$))
.subscribe(_ => this.router.navigate(['/somewhere']));
有没有办法完全消除 takeUntil 的需要,只使用 Async 管道。我理想中想要的是像这样在 ngSubmit 中有异步管道:
<form (ngSubmit)="submit(value) | async">
但既然这是不可能的,还有其他方法吗?
一些相关资源:
A Comprehensive Guide to Angular onPush Change Detection Strategy Using the takeUntil RxJS Operator to Manage Subscriptions Declaratively RxJS: Avoiding takeUntil Leaks The Ultimate Answer To The Very Common Angular Question: subscribe() vs | async Pipe【问题讨论】:
【参考方案1】:有趣的事实。如果你使用 Angular 提供的 HttpClient,你不需要取消订阅。收到响应后,调用 complete() 方法。
【讨论】:
虽然这是事实,但取消订阅任何 observable 还有其他好处。这不再是关于内存泄漏,而是关于减轻副作用 - 例如。您使用 HttpClient 执行查询,但随后您决定导航到另一个页面。如果不取消订阅,任何完成逻辑仍将执行,但如果您取消订阅,您将中止底层 XHR 并删除所有侦听器。以上是关于如何在不订阅 Angular 表单提交的情况下创建/更新项目的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Django、Ajax、jQuery 在不刷新页面的情况下提交表单?