Угловой удалить locationStrategyListener на ngDestroy - PullRequest
0 голосов
/ 11 декабря 2018

Мне интересно, почему моя проблема кажется такой нетривиальной: поскольку мы реализовали запросы на стороне сервера, нумерацию страниц и т. Д., Мы должны запрашивать наш API всякий раз, когда пользователь вносит изменения в таблицу (например, при запросе имени =х клиент отправляет запрос с соответствующими параметрами запроса на сервер).Это также означает, что нам нужно запрашивать серверную часть при возвращении в историю, особенно при нажатии кнопки «Назад» в браузере.

Это прекрасно работает со следующим кодом:

constructor(private locationStrategy: LocationStrategy) { }

ngOnInit() {
    this.locationStrategy.onPopState(() => {
        this.refreshHistory();
    })
}

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

Iкаким-то образом нужно удалить любой EventListener в интерфейсе ngDestroy, но locationStrategy, похоже, не предоставляет такую ​​возможность.Есть ли (чистый) способ добиться этого?

Заранее спасибо!

PS: Пожалуйста, поправьте меня, если это абсолютно неправильный подход.Я больше привык к реализации бэкэндов, чем веб-интерфейсов.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Решение для этого, на самом деле, довольно легко, если прочитать всю документацию по RxJS.Мы используем оператор fromEvent для создания подписки на событие onPopState.От этой подписки мы можем легко отписаться, и все работает как шарм.

import {fromEvent, Subscription} from "rxjs";

export class CommentAllComponent implements OnInit, OnDestroy {

    private backEvent: Subscription;

    ngOnInit() {
        this.backEvent = fromEvent(window, 'popstate').subscribe(() => {
        // doCustomRefresh()
        });
    }

    ngOnDestroy(): void {
        this.backEvent.unsubscribe();
    }
}
0 голосов
/ 11 декабря 2018

Альтернативный подход

Вместо использования LocationStrategy я бы посоветовал вам взглянуть на использование queryParams маршрута.Вы можете подписаться на них в ngOnInit и отказаться от подписки в ngOnDestroy.Похоже, что это будет хорошо работать в вашем случае, когда вы в основном пытаетесь вернуться к предыдущему состоянию в компоненте.

Например, пользователь может щелкнуть обратно отсюда:

localhost:4200 / # / table? FilterString = foo & colSort = idAscending

И в конечном итоге здесь:

localhost: 4200 / # / table? FilterString = foo

export class MyComponent implements OnInit, OnDestroy {
  paramSub: Subscription;
  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.paramSub = this.route.queryParams.subscribe(params => {
      console.log(params); // query params changed, getData()
    })
  }

  ngOnDestroy(){
    this.paramSub.unsubscribe();
  }
}

ДополнительноДля угловых документов я нашел эту статью полезной для начала работы с QueryParams https://alligator.io/angular/query-parameters/

Extra

Проблема с LocationStrategy, как вы заметили, не предоставленаудалить слушателя.

Я не знаю достаточно, чтобы сказать, невозможно ли продолжать этот подход, но он, безусловно, более сложный.Вы можете попробовать использовать именованную функцию вместо анонимной функции, например, так:

  constructor(private location: LocationStrategy) { }

  ngOnInit() {
    this.location.onPopState(this.popStateHandler);
  }

  popStateHandler(event){
    console.log('handle onPopState', event);
  }

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

...