Подчинение наблюдаемому ReplaySubject не дает желаемого эффекта прокрутки - PullRequest
0 голосов
/ 25 марта 2020

При переходе от страницы 1 (после выполнения поиска от компонента A) к целевой странице 2 я использую сервис с наблюдаемой, чтобы сообщить компоненту B (подписывается на наблюдаемую) на странице 2, что произошел новый поиск , Я ожидаю, что страница 2 прокручивается вниз при загрузке, поэтому результаты поиска, проведенного на странице 1, отображаются вверху страницы 2. Но когда загружается страница 2, прокрутка вниз не происходит. Прокрутка вниз происходит при любом последующем поиске, выполняемом компонентом A на странице 2 (оба компонента A и B являются дочерними элементами компонента C (который относится к странице 2). Я пытаюсь выяснить, почему прокрутка не происходит когда инициируется страница 2. Тем более, что я подписываюсь на наблюдаемый объект ReplaySubject. Вот соответствующий код:

Компонент A (используется для поиска на обеих страницах 1 и 2):

processQuery() {//take at face value that this section works without a glitch, as intended
    this.subscriptions.add(this.httpService.callDatabase<searchParamsClass>('post', this.url, this.searchParams).subscribe(
      resp => {
        this.searchEvent.emit(resp);//emits search results to page 2
        localStorage.setItem('previousSearchData', JSON.stringify(resp));
        this.errorMessage = false;
        this.router.navigate(['/page2, this.searchType], { queryParams: this.navigationExtras});
      },
      error => this.errorMessage = true,
      () => {
        this.dataSharing.transferData({'origin':'componentA', 'data':{'newSearch':true}});
      }));
  }

Служба обмена данными (используется для связи между компонентами A и B):

export class DataSharingService {
  outgoingData = new ReplaySubject;
  outgoingData$ = this.outgoingData.asObservable();
  constructor() { }
  transferData(incomingData: object){
    console.log('incoming data: ', incomingData);
    this.outgoingData.next(incomingData);
  }
}

Компонент B (подписывается на наблюдаемую службу обмена данными) и для получения информации для выполнения требуемой прокрутки вниз:

export class componentB implements DoCheck, OnDestroy, OnInit {
  title: string = 'Show';
  flag: object = {};
  show: boolean = false;
  subscriptions: Subscription = new Subscription();

  constructor(private dataSharing: DataSharingService,
    private setAttributes: SetAttributesService) {
    this.subscriptions.add(this.dataSharing.outgoingData$.subscribe(
      res => {
        this.flag = JSON.parse(JSON.stringify(res));
      }
    ))
  }

  ngOnInit() {
    this.emitStuff(); //emits data to component C (parent) and works as intended
    if (localStorage.getItem('show')) {
      this.show = JSON.parse(localStorage.getItem('show'));
      if (this.show == true) {
        this.title = 'Hide';
        this.setAttributes.setAttributes({ 'all': { 'class': 'col-auto collapse show bg-white mt-3 d-md-block' }, 'title': { 'class': 'd-md-none filterIcon', 'aria-expanded': 'true' } });
      } else {
        this.title = 'Show';
        this.setAttributes.setAttributes({ 'all': { 'class': 'col-auto collapse bg-white mt-3 d-md-block' }, 'title': { 'class': 'd-md-none filterIcon', 'aria-expanded': 'false' } });
      };
    };
  }

  ngDoCheck() {
    //scroll to results and adjust display when user performs new Search
    if (this.flag['origin'] == 'componentA' && this.flag['data']['newSearch'] == true) {
      this.newSearch();
      this.flag['data'] = {} //resetting this.flag
    };
  }

  ngOnDestroy() {
    this.subscriptions.unsubscribe();
    this.clear();
  }

  newSearch() {
    this.clear();
    this.setAttributes.setAttributes({ 'all': { 'class': 'col-auto collapse bg-white mt-3 d-md-block' }, 'title': { 'class': 'd-md-none filterIcon', 'aria-expanded': 'false' } });
    this.title = 'Show';
    this.show = false;
    $('html, body').animate({ scrollTop: $('#title').offset().top }, 'slow'); //this piece is what doesn't work when component B is first initialized, but works for subsequent searches from component A (which doesn't require component B to be reinitialized).
  }

  clearFilters() {
    this.searchCategories.forEach(category => {
      category['options'].forEach(option => {
        option.checked = false;
      })
    });
    localStorage.removeItem('previous');
    this.searchOptions = {};
    this.currentOptions = {};
    this.emit();
    $('html, body').animate({ scrollTop: $('#title').offset().top }, 'slow');
  }

Когда я помещаю this.flag['data'] = {} (в ngDoCheck) в setTimeout, это, кажется, делает свое дело. Но я хочу по возможности избегать использования setTimeout (я понимаю, что это не очень хорошая практика). Даже если Я должен был использовать setTimeout здесь из отчаяния, но я не понимаю, почему прокрутка вниз на странице 2 не работает, когда страница 2 инициализируется впервые, но отлично работает при последующих поисках на стр. 2.

...