Должен ли я отказаться от подписки на наблюдаемые ActivatedRoute (например, params)?

Я нахожу много примеров, когда ActivatedRoute Observables, такие как params или url, подписываются, но не отписываются.

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);
}
  • Уничтожаются ли объекты маршрута и подписки автоматически и создаются ли заново при создании каждого компонента?
  • Должен ли я заботиться об отказе от подписки на эти Observables?
  • Если нет, можете ли вы объяснить, что происходит с деревом объектов ActivatedRoute в _6 _._ 7_?

person hgoebl    schedule 14.12.2016    source источник
comment
Не нужно отказываться от подписки на параметры роутера. Вам нужно будет отказаться от подписки, только если вы создали на уровне компонентов.   -  person kk4You    schedule 27.06.2020
comment
Да, вам нужно, у меня были случаи, когда мой компонент разрушался, а затем подписка queryParams срабатывала в последний раз после этого.   -  person Daniel    schedule 04.02.2021


Ответы (5)


Из документации:

Подписываясь на наблюдаемый объект в компоненте, вы почти всегда соглашаетесь отказаться от подписки при уничтожении компонента.

Есть несколько исключительных наблюдаемых, где в этом нет необходимости. Среди исключений - наблюдаемые ActivatedRoute.

ActivatedRoute и его наблюдаемые объекты изолированы от самого маршрутизатора. Маршрутизатор уничтожает маршрутизируемый компонент, когда он больше не нужен, и внедренный ActivatedRoute умирает вместе с ним.

Не стесняйтесь отказаться от подписки в любом случае. Это безвредно и никогда не бывает плохой практикой.

person Milad    schedule 28.12.2016
comment
Как отказаться от подписки, ведь это никогда не бывает плохой практикой. Документы вообще не приводят примеров отказа от подписки - person TetraDev; 24.08.2017
comment
@TetraDev Как это .. ngOnInit () {this.routeSub = this.route.paramMap .subscribe (params = ›{this.event = this.eventService.getEvent (+ params.get ('id'));}); } ngOnDestroy () {this.routeSub.unsubscribe (); } - person DJDJ; 11.10.2017
comment
как поживаете unsubscribe, если вы подписываетесь на ActivatedRoute в app.component? - person candidJ; 24.09.2018
comment
@candidJ, вы можете отказаться от подписки таким же образом, как описано в @DJDJ, но поскольку app.component будет жить до тех пор, пока существует приложение, в любом случае нет реальной необходимости отказываться от подписки. - person crollywood; 29.08.2019
comment
Привет, @Milad, не могли бы вы указать мне источник, где я мог бы найти ВСЕ исключения из правила «отписаться»? Спасибо. - person PaxForce; 14.01.2020
comment
@PaxForce не уверен, есть ли источник, однако все, что создано самой командой Angular, не нужно отписывать (насколько я помню). Например, события маршрута, события HTTP, события мыши и клавиатуры и т. Д. Все, что вы создаете самостоятельно, например myevent = new EventEmitter () ... или myevent = new Subject (), требует от вас отказа от подписки (технически все зависит от характер события, но то, что я сказал, является практическим правилом). Я предлагаю всегда отказываться от подписки, чтобы вы точно знали, что происходит - person Milad; 15.01.2020
comment
Я обновил ссылку на документацию в этом ответе, но учтите, что вы все равно можете отказаться от подписки. Это безвредно и никогда не бывает плохой практикой. предложения больше нет в документации. - person Sébastien; 27.06.2020
comment
Я только что обнаружил ошибку в своем коде, вызванную срабатыванием подписки queryParams в последний раз после вызова ngOnDestroy. Итак, чтобы перестраховаться, я сейчас отказываюсь от подписки даже на наблюдаемые ActivatedRoute. - person Daniel; 04.02.2021
comment
Еще одно исключение - HttpClient подписка. т.е. не нужно отказываться от подписки. - person Sampath; 31.05.2021

Компонент будет уничтожен, а routerState перестанет ссылаться на него, когда маршрутизатор перейдет на другой маршрут, что сделает их свободными для сбора мусора, включая наблюдаемый.

Если вы передадите ссылки на этот компонент другим компонентам или службам, компонент не будет собираться мусором, и подписка будет оставаться активной, но я уверен (без проверки), что наблюдаемое будет выполнено маршрутизатором при навигации. прочь и вызовет отмену подписки.

person Günter Zöchbauer    schedule 27.12.2016
comment
Это означает, что ActivatedRoute - это новый экземпляр после каждой навигации по маршруту, верно? Как тогда будет работать подписка на измененные параметры маршрута? Может быть, вы могли бы объяснить особый жизненный цикл ActivatedRoute? Создается ли RouterState дерево из корня после каждой навигации? Если компонент будет уничтожен после навигации, это вызовет мерцание !? - person hgoebl; 27.12.2016
comment
Если вы перейдете к другому маршруту, то компонент будет уничтожен, если вы вернетесь назад, он будет воссоздан. Если у вас есть один и тот же компонент на разных маршрутах, и вы переходите от одного к другому, компонент также уничтожается и создается заново. Только при навигации, когда изменяются только параметры маршрута, экземпляр компонента используется повторно. Последние версии поддерживают индивидуальную стратегию повторного использования. См. Также github.com/angular/angular/issues/7757#issuecomment-236737846 и softwarearchitekt.at/post/2016/12/02/ - person Günter Zöchbauer; 27.12.2016
comment
Спасибо Зочи за ответ. Я не был уверен, кто получит награду, но у Милад только 1 очко репутации, а у вас уже 149к. Кстати, его ответ подтверждается ссылкой на официальные документы. В следующий раз, очень скоро, ты снова станешь мужчиной :-) - person hgoebl; 02.01.2017
comment
Не стоит беспокоиться. С Новым Годом :) - person Günter Zöchbauer; 02.01.2017

В качестве победного ответа цитаты о subscriptions к ActivatedRoute, Angular unsubscribes автоматически.

Маршрутизатор уничтожает маршрутизируемый компонент, когда он больше не нужен, и введенный ActivatedRoute умирает с ним.

Если вы хотите узнать, как unsubscribe из Observables:

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();
  }

}
person Marian07    schedule 14.01.2018

Каждый раз, когда вы добавляете подписку на компонент, вам почти всегда нужно отказаться от подписки, когда компонент уничтожается. Но для подписки на параметры маршрута Activated не требуется отказываться от подписки, поскольку маршрутизатор уничтожает подписку всякий раз, когда она больше не нужна.

person thegautamnayak    schedule 25.11.2018

Вызовы Http Observables и Router Observables не нужно отказываться от подписки вручную. В случае, если вы обрабатываете другой вид наблюдаемого или собственное наблюдаемое, вы должны сделать это с помощью ngOnDestroy (). Вы делаете это, вызывая метод unsubscribe () внутри объекта Suscription, в котором вы храните наблюдаемое в компоненте.

person Yair Abad    schedule 18.05.2020