如何在不订阅 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 在不刷新页面的情况下提交表单?

在不使用 JavaScript 的情况下,如何在选择字段集中时使 Enter 键提交表单?

如何在不通过 jQuery 提交的情况下强制进行 html5 表单验证