Многократная подписка - PullRequest
       19

Многократная подписка

0 голосов
/ 07 января 2020

В одном компоненте у меня две подписки, одна для параметров запроса, одна для http GET-запроса. На этой странице пользователь также имеет возможность переключаться между различными типами данных (может отображаться только один тип). Когда пользователь щелкает одну опцию, параметр запроса обновляется, и подписка обновляется, поэтому запрос HTTP GET вызывается снова, и данные также обновляются, как показано ниже:

constructor(private service: DataService, private route: ActivatedRoute) {}

ngOnInit() {
        this.route.queryParams.subscribe(params => {
            this.dataType = params["dataType"];
                this.service
                    .getData(this.dataType)
                    .subscribe(data => {
                        this.data=data;
                    })
        })
}

В html:

  [queryParams]="{ dataType: row.dataType}"

Проблема в том, что каждый раз, когда пользователь щелкает по другому типу данных, новая подписка создается из запроса HTTP GET, потому что все происходит внутри одного компонента. Таким образом, при создании компонента: 2 подписки, пользователь нажимает новый тип данных: загружены новые данные и 3 подписки, пользователь нажимает другой тип данных, загружаются новые данные и 4 подписки и так далее. Как вы можете себе представить, после 4-5 нажатий страница просто вылетает.

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

Ответы [ 4 ]

2 голосов
/ 07 января 2020

Методы Http - это холодные наблюдаемые, поэтому вам не нужно отписываться. Он будет отменен автоматически.

Вместо этого вам следует отписаться от подписки router.queryParams, которая является популярной. Эта подписка создается несколько раз в вашем коде.

Это можно сделать в ngOnDestroy ловушке жизненного цикла

routerSub: Subscription;

constructor(private service: DataService, private route: ActivatedRoute) {}

ngOnInit() {
        this.routerSub = this.route.queryParams.subscribe(params => {
            this.dataType = params["dataType"];
                this.service
                    .getData(this.dataType)
                    .subscribe(data => {
                        this.data=data;
                    })
        })
}

ngOnDestroy() {
    this.routerSub.unsubscribe();
}
2 голосов
/ 07 января 2020

Немного Rx JS конвейерные операторы должны решить эту проблему:

switchMap - отменит предыдущий http-запрос и переключится на последний
использовать takeUntil метод для отписки
tap для побочного эффекта (немного некрасиво не делать этого в рамках подписки)

ngOnInit() {
  this.route.queryParams.pipe(
    map(params => params["dataType"]),
    tap(dataType => {
      this.dataType = dataType
    }),
    switchMap(dataType => this.service.getData(this.dataType)),
    takeUntil(this.destroyed$)
  ).subscribe(data => {
    this.data = data;
  })
}

Редактировать - сделать takeUntil последним оператором!

1 голос
/ 07 января 2020

сохраните текущую подписку в переменной, а затем закройте ее, прежде чем создавать новую:

subscription: currSubscribtion;

constructor(private service: DataService, private route: ActivatedRoute) {}

ngOnInit() {
  this.route.queryParams.subscribe(params => {
    if (currSubscribtion) {
      this.currSubscribtion.unsubscribe()
    }
    
    this.dataType = params["dataType"];
    this.currSubscribtion = this.service.getData(this.dataType)
      .subscribe(data => {
          this.data=data;
      })
  })
}
0 голосов
/ 07 января 2020

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

Вы можете обновить свой код следующим образом:

this.route.queryParams.pipe(
    switchMap(params => this.service.getData(params["dataType"]))
).subscribe(data => this.data = data);

Чтобы решить проблему с подпиской, вы пытались добавить функцию ngOnDestroy()?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...