我是否必须取消订阅ActivatedRoute(例如params)可观察对象?


77

我发现了许多示例,其中ActivatedRouteObservable喜欢paramsurl已订阅但未取消订阅。

constructor(private route: ActivatedRoute) {}

ngOnInit() {
  this.route.params
    // (+) converts string 'id' to a number
    .switchMap((params: Params) => this.service.getHero(+params['id']))
    .subscribe((hero: Hero) => this.hero = hero);
}
  • 路径对象和订阅是否会自动销毁,并在每次创建组件时都重新创建?
  • 我是否需要取消订阅那些邮件Observable
  • 如果没有,您能否解释一下中的ActivatedRoute对象树的情况RouterrouterState

无需取消订阅任何路由器参数。仅当您在组件级别创建时才需要取消订阅。
kk4You

Answers:


160

从文档

订阅组件中的可观察对象时,几乎总是在组件被破坏时安排退订。

有一些不需要观察的异常观测值。可以看到ActivatedRoute可观察项。

ActivatedRoute及其可观察物与路由器本身绝缘。当不再需要路由组件时,路由器将销毁该路由组件,并且注入的ActivatedRoute随之死亡。

随时可以退订。这是无害的,绝不是坏习惯。


4
您如何退订,因为这从来都不是坏习惯。文档没有给出所有取消订阅的示例
TetraDev

8
@ ngOnInit(){this.routeSub = this.route.paramMap .subscribe(params => {this.event = this.eventService.getEvent(+ params.get('id'));}); } ngOnDestroy(){this.routeSub.unsubscribe(); }
DJDJ

unsubscribe如果您订阅ActivatedRoutein,该怎么办app.component
candidJ

@candidJ您可以按照@DJDJ所述的相同方式取消订阅,但是由于app.component应用程序的寿命将一直存在,因此实际上并不需要取消订阅。
crollywood

1
我更新了此答案中的文档链接,但请注意,“无论如何都可以退订。这是无害的,绝不是坏习惯。” 句子不再在文档中。
塞巴斯蒂安

7

当路由器导航到其他路由时,该组件将被破坏,并且routerState将变为未引用,这将使它们可以自由获取垃圾,包括可观察的垃圾。

如果将对该组件的引用传递给其他组件或服务,则不会对该组件进行垃圾回收,并且订阅将保持活动状态,但是我确信(无需验证)导航时,可观察对象将由路由器完成离开并导致订阅取消。


1
这意味着这ActivatedRoute是每次路线导航之后的新实例,对吗?然后如何订阅更改的路线参数?也许您可以解释一下的特殊生命周期ActivatedRouteRouterState每次导航后是否从根重新创建树?如果导航后组件被破坏,将导致闪烁!
hgoebl

2
如果导航到其他路线,则该组件将被破坏,而向后导航,则将重新创建该组件。如果您在不同的路线上具有相同的组件,并且从一个导航到另一个,则该组件也会被破坏并重新创建。仅当您导航时(以便仅更改路由参数),才可以重用组件实例。最新版本支持自定义重用策略。又见github.com/angular/angular/issues/7757#issuecomment-236737846softwarearchitekt.at/post/2016/12/02/...
冈特Zöchbauer

感谢Zöchi的回答。我不确定谁会得到赏金,但是Milad只有1分的声誉,而您已经有149k。顺便说一句,他的回答通过引用官方文档来证明。下次,很快,您将再次成为男人:-)
hgoebl

别担心。新年快乐:)
君特Zöchbauer

6

当获胜的答案有关时,Angular会自动报价subscriptionsActivatedRouteunsubscribes

当不再需要路由组件时,路由器将销毁该路由组件,并且注入的ActivatedRoute随之死亡。

如果你想知道如何unsubscribeObservables

import { Component, 
         OnInit,
         OnDestroy }      from '@angular/core';
import { ActivatedRoute } from '@angular/router'; 
// Type
import { Subscription } from 'rxjs/Subscription';


@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss']
})
export class ExampleComponent implements OnInit, OnDestroy {
  paramsSubscription : Subscription;

  constructor(private activatedRoute : ActivatedRoute) { }

  /* Angular lifecycle hooks
  */
  ngOnInit() {
    console.log("Component initialized");
    this.paramsSubscription = this.activatedRoute.params.subscribe( params => {

    });
  }

  ngOnDestroy() {
    console.log("Component will be destroyed");
    this.paramsSubscription.unsubscribe();
  }

}

1

每当添加订阅组件时,几乎总是需要在组件被销毁时取消订阅。但是订阅“激活的路由”参数并不需要取消订阅,因为路由器会在不再需要订阅时破坏订阅。


0

Http可观察者调用和路由器可观察者不需要手动退订。如果您处理其他类型的可观察对象或您自己的可观察对象,则应在ngOnDestroy()上进行操作。您可以在Suscription对象中调用unsubscribe()方法,将可观察对象存储在组件中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.