У меня есть главная страница с парой разделов. Доступ к каждому разделу можно получить, введя его название фрагмента в URL (например, www.website.com/#introduction - откроет домашнюю страницу и автоматически перейдет к разделу введения). Для этого мне нужно получить контейнерный элемент секции и запустить на нем функцию .scrollIntoView ().
Что я сделал:
- Элемент списка, который я создал, store (ngrx), в котором хранятся ElementRef (s) разделов.
- В каждом компоненте раздела (расположенном в HomeComponent - родительском элементе разделов) я помещаю
@ViewChild()
, указывающий на элемент. @ViewChild(‘container’, { static: true }) private container: ElementRef;
- Затем в
ngAfterViewInit()
этого компонента секции я помещаю Store.dispatch()
, в котором хранится мой ElementRef.
this.store.dispatch(new HomeActions.SetElementRef({
linkName: COMP_LINK_NAME,
elementRef: this.container
}));
Затем в HomeComponent
Слушаю разделы Магазин риф this.store.select('sectionRefs')
. Отфильтровал его, если его undefined
(так как по умолчанию инструкция store = default пуста).
this.sectionRefs$ = this.store.select('sectionRefs').pipe(
map((data: { sectionRefs: SectionReference[] }) => data.sectionRefs), // transform to a more convenient object
tap((sectionRefs: SectionReference[]) => this.sectionRefs = sectionRefs), // Updates the sectionRefs array regardless the completion of it (filter below)
filter((sectionRefs: SectionReference[]) => { // No emission until sectionRefs Element Refs are completed
return sectionRefs.find((sectionRef: SectionReference) => {
return (
sectionRef.element === undefined ||
sectionRef.element === null ||
sectionRef.element.nativeElement.offsetHeight === 0 && sectionRef.element.nativeElement.offsetWidth === 0
);
}) === undefined // Means that no incompleted sectionRef was found
}),
distinctUntilChanged(
(prev: SectionReference[], next: SectionReference[]) => JSON.stringify(prev) === JSON.stringify(next)
),
first()
);
HomeCompoent: И в конце концов я прослушал фрагмент ActivatedRoute.fra, чтобы проверить, какой ElementRef релевантен для прокрутки. HomeComponent: Активируйте .scrollIntoView () на соответствующем ElementRef.
Проблема в том, что я делаю это, когда страница загружена, поэтому ElementRef.nativeElement.scrollIntoView()
прокручивается в неправильное место. Я проверил, чтобы увидеть полученное offsetHeight (ElementRef.nativeElement.offsetHeight
), и оно также было неверным. Таким образом, в каждом разделе компонента я обернул действие Store.dispatch()
с setTimeout()
setTimeout(() => {
this.store.dispatch(new HomeActions.SetElementRef({
linkName: COMP_LINK_NAME,
elementRef: this.container
}));
}, 150);
И это работает! Но это похоже на очень плохую практику, чтобы делать эту работу вокруг.
Есть ли другое решение?