首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在组件销毁时销毁reactive FormControl?

如何在组件销毁时销毁reactive FormControl?
EN

Stack Overflow用户
提问于 2017-06-17 18:11:50
回答 3查看 9.2K关注 0票数 4

我有一个带有FormControl和订阅的组件,它的值发生了变化:

代码语言:javascript
复制
@Component(...)
export class FooComponent implements OnInit, OnDestroy {
  fooFormControl: FormControl;

  ...

  ngOnInit() {
    this.fooFormControl.valueChanges.subscribe(
      () => {...},
      () => {},
      () => {
        // never happens
      },
    );
  }

  ngOnDestroy() {
    //happens
  }
}

但是当组件被销毁时,FormControl元素不会被销毁,onComplete回调也不会发生。

在组件销毁时销毁FormControl元素的正确方法是什么?

EN

回答 3

Stack Overflow用户

发布于 2017-06-17 20:51:42

FormControl可观察对象不应该被完成,尽管如果有一些属于完整回调的逻辑,也可以手动完成。

由于valueChanges是事件发射器,并且继承自RxJS Subject,因此可以取消订阅或完成:

代码语言:javascript
复制
ngOnDestroy() {
  this.fooFormControl.valueChanges.complete();  
  // and/or
  this.fooFormControl.valueChanges.unsubscribe();
}

EventEmitter有可能不会成为未来的主题。这可能会导致破坏更改,但目前它仅依赖于RxJS。

票数 2
EN

Stack Overflow用户

发布于 2017-09-27 21:49:41

这里有两个想法可能会对你有所帮助。我不确定它们是否是“正确的方式”,但到目前为止,它对我来说工作得很好。除此之外,我像往常一样在ngOnDestroy上取消订阅。

通过takeUntil介绍您自己的主题,#1强制完成

在TypeScript中,valueChanges属性的类型为Observable。如果您不想绕过这个问题并进入主题,那么您可以使用takeUntil操作符来介绍您自己的主题。这将允许您在valueChanges可观察性之上的级别强制传播完成。重要的是,不要将takeUntil操作符放在切换映射之前,否则切换到可观察的操作将继续,并且您的订阅不会被取消!出于这个原因,我把它放在订阅操作符之前。

下面是一个示例:

代码语言:javascript
复制
const stop = new Subject();

// simulate ngOnDestroy
window.setTimeout(() => {
  stop.next();
  stop.complete();
}, 3500);

Observable
  .interval(1000)
  .takeUntil(stop)
  .subscribe(
    () => { console.log('next'); }, 
    () => { console.log('error'); }, 
    () => { console.log('complete'); }
  );

下面是一个有效的示例:https://rxviz.com/v/RoQNBnOM

#2将FormBuilder添加到组件的提供者列表中

这就是我通常做的事情。实际上,我通常将表单封装在使用FormBuilder的服务中,但效果是一样的。在此级别提供服务将在每次创建组件时销毁并重新创建服务。我之所以开始这样做,是因为我一直有一些奇怪的bug,这些bug是由valueChanges创建的可观察到的流引起的,这些流在组件的生命周期之后仍然存在。当组件被重新创建时,它们会被重新订阅,诸如此类。

下面是一个示例:

代码语言:javascript
复制
@Component({
    selector: 'my-form',
    templateUrl: './my-form.component.html',
    styleUrls: ['./my-form.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
    providers: [ FormBuilder ] // <-- THIS PART
})
export class MyFormComponent implements OnInit, OnDestroy {
}

请注意,这实际上并不会传播完成。但它每次都会给你一个新的来源主题。

票数 2
EN

Stack Overflow用户

发布于 2017-06-17 18:13:52

你不能销毁你的表单控件。组件中的所有内容都将被销毁,但事件可以保留在您的应用程序中。所以你可以取消订阅它的事件。

代码语言:javascript
复制
@Component(...)
export class FooComponent implements OnInit, OnDestroy {
  fooFormControl: FormControl;
  var subscriber;

  ...

  ngOnInit() {
    this.subscriber = this.fooFormControl.valueChanges.subscribe(
      () => {...},
      () => {},
      () => {
        // never happens
      },
    );
  }

  ngOnDestroy() {
    this.subscriber.unsubscribe();
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44603327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档