Мое приложение имеет два родительских компонента, A и B, каждый в своих собственных модулях (модули A и B, соответственно). Компонент A включает дочерний компонент C из своего собственного модуля (модуль C). Компонент B включает дочерний компонент C (из модуля C) и дочерний компонент B1 из модуля B. Все взаимодействия и поведение между различными родительскими / дочерними компонентами работают нормально. Проблема, с которой я столкнулся, заключается в попытке заставить компонент (B1) прокрутить элемент (elemOfInterest) к вершине области просмотра в ответ на флаг (flagA), который компонент C излучает через службу обмена данными.
Когда я нажимаю кнопку отправки формы дочернего компонента C из шаблона компонента A, я перенаправляем на компонент B. Но scrollToView в дочернем компоненте B1 не работает без setTimeout. После запуска жизненного цикла компонента B1 ngOnInit нажатие кнопки отправки формы компонента C (на этот раз из шаблона компонента B) приводит к тому, что метод scrollToView работает идеально без использования setTimeout. Я не могу понять, почему ngOnInit мешает scrollToView в компоненте B1. Вот мой код:
Компонент C .component.ts:
export class ComponentC implements OnInit {
constructor(private dataSharing: DataSharingService) {}
ngOnInit() {
doSomething(){
this.dataSharing.transferData({'data':{'flagA':true}});
}
}
}
Компонент C .component. html:
<form class="mx-auto" [formGroup]="searchForm" (ngSubmit)="doSomething()">
<div> … </div>
<div> <button type="submit">Submit</button> </div>
</form>
КомпонентB1. component.ts
export class ComponentB1 implements OnDestroy, OnInit {
subscriptions: Subscription = new Subscription();
constructor(private dataSharing: DataSharingService) {}
ngOnInit() {
this.subscriptions.add(
this.dataSharing.outgoingData$.subscribe(data => {
this.onSharedData(data);
})
)
}
onSharedData(data) {
if (Object.keys(data).length && Object.keys(data['data']).length) {
switch (true) {
case data['data']['flagA']:
this.func1();
break;
case data['data']['flagB']:
this.func2();
break;
}
}
}
ngOnDestroy() {this.subscriptions.unsubscribe()}
func1(){
//do something simple, like set html element values, etc.
setTimeout(()=>document.getElementById('elemOfInterest').scrollIntoView({behavior: 'smooth', block: 'start', inline: 'nearest'}));
}
}
код службы обмена данными:
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataSharingService {
outgoingData$ = new ReplaySubject(1);
constructor() {}
transferData(incomingData: object){
this.outgoingData$.next(incomingData);
}
}
Для чего бы то ни было, я также попытался использовать jquery
$('html, body').animate({ scrollTop: $('#elemOfInterest).offset().top }, 'slow')
scrollToView, но все еще требует setTimeout, когда компонент B1 впервые запускается для правильной работы прокрутки. Любая идея, как выполнить sh поведение прокрутки без использования setTimeout?