для дополнения для макета я импортирую Bootstrap 5 утилит. Достаточно, чтобы кнопки внутри первой строки не имеют маржи с заголовком моего приложения (для которого я не собираюсь добавлять код).
Когда я комментирую element.scrollintoview (true); Проблема не возникает. В конструкторе. < /p>
Обратите внимание на CSS в компоненте оболочки. Он должен сохранить выбранную элемент в представлении и, по крайней мере, один другой элемент выше выбранного, если индекс не является нулевым, поэтому пользователь может нажать, чтобы подняться или вниз.
Код: Выделить всё
import { Component, computed, effect, ElementRef, inject, viewChildren } from '@angular/core';
import { MyStore } from '../../../stores/my-store.store';
@Component({
selector: 'app-my-list-wrapper',
standalone: true,
templateUrl: './my-list-wrapper.component.html'
})
export class MyListWrapperComponent {
listItems = viewChildren('orderedListItem');
myStore = inject(MyStore);
readonly items = computed(() =>
this.myStore
.getItems()
.map((result) => result.model)
);
selected= computed(
() => this.myStore.selected()?.index - 1
);
constructor() {
effect(() => {
const index = this.selected();
if (index >= 0 && !!this.listItems()) {
setTimeout(() => this.scrollToTop(index), 0); // Ensure DOM is updated before scrolling
}
});
}
setCurrent(index: number) {
if (step < this.myStore.items().length && step >= 0) {
this.myStore.setSelected(
this.myStore.items()[index]
);
this.scrollToTop(index);
}
}
scrollToTop(index: number) {
if (index > 0) index--;
const element = this.listItems().at(index)?.nativeElement;
if (element) {
element.scrollIntoView(true);
} else {
console.error('List item not found at index:', index);
}
}
}
< /code>
Шаблон обертки списка: < /p>
@for (item of items(); track item; let index = $index) {
{{ index + 1 }}
{{ item }}
}
< /code>
класс оболочки: < /p>
import { Component, OnInit, computed, inject } from '@angular/core';
import { MyStore } from '../../stores/my-store.store';
import { ActivatedRoute, Router } from '@angular/router';
import { MatDividerModule } from '@angular/material/divider';
import { MyOtherStore } from '../../stores/my-other-store.store';
import { MyListWrapperComponent } from './list-wrapper/list-wrapper.component';
import { MyItemDetailsComponent } from './item-details/item-details.component';
@Component({
selector: 'app-shell',
standalone: true,
imports: [
MatDividerModule,
MyListWrapperComponent,
MyItemDetailsComponent
],
templateUrl: './shell.component.html',
styleUrl: './shell.component.scss',
})
export class ShellComponent implements OnInit {
readonly route = inject(ActivatedRoute);
readonly router = inject(Router);
myStore = inject(MyStore);
myOtherStore = inject(MyOtherStore);
readonly selectedDetails = computed(() =>
this.myStore
.items()
.flatMap((result) => result.details)
);
selected = this.myOtherStore.selected;
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id') ?? 'error';
this.myStore.fetchItems(id);
}
}
< /code>
Шаблон оболочки: < /p>
{{ title }}
@if (selected().title != '') {
{{ selected().title }}
}
@else {
No Selected
}
@if (selected().title != '') {
}
@else {
My List Wrapper Goes Here
}
< /code>
shell css: < /p>
.hl-container {
height: calc(
90vh - 50px
); // 10vh is the height of the shell header, 50px is the height of the application header
overflow-y: scroll;
}
.hl-container::-webkit-scrollbar {
display: none;
}
< /code>
Что я уже пробовал: < /p>
Я получал выбранный элемент из Div с #scrollcontainer для них. < /p>
scrollToTop(index: number) {
const itemElement = this.scrollContainer().nativeElement.querySelector(`#ordered-item-${index}`);
if (itemElement) {
const container = this.scrollContainer().nativeElement;
const itemOffsetTop = itemElement.offsetTop;
container.scrollTop = itemOffsetTop;
} else {
console.error('List item not found at index:', index);
}
}
< /code>
scrollToTop(index: number) {
const itemElement = this.scrollContainer().nativeElement.querySelector(`#ordered-item-${index}`);
if (itemElement) {
const container = this.scrollContainer().nativeElement;
const itemOffsetTop = itemElement.offsetTop;
container.scrollTop = itemOffsetTop - container.offsetTop;
} else {
console.error('List item not found at index:', index);
}
}
< /code>
scrollToTop(index: number) {
if (index > 0) index--;
const itemElement = this.scrollContainer().nativeElement.querySelector(`#ordered-item-${index}`);
if (itemElement) {
const container = this.scrollContainer().nativeElement;
const itemRect = itemElement.getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
const offset = itemRect.top - containerRect.top + container.scrollTop;
container.scrollTo({ top: offset, behavior: 'smooth' });
} else {
console.error('List item not found at index:', index);
}
}
< /code>
scrollToTop(index: number) {
if (index > 0) index--;
const itemElement = this.scrollContainer().nativeElement.querySelector(`#ordered-item-${index}`);
if (itemElement) {
const container = this.scrollContainer().nativeElement;
const itemOffsetTop = itemElement.offsetTop;
container.scrollTo({ top: itemOffsetTop, behavior: 'smooth' });
} else {
console.error('List item not found at index:', index);
}
}
< /code>
Hoping someone here can at least explain what is happening with element.scrollIntoView(true)Подробнее здесь: https://stackoverflow.com/questions/795 ... ngular-app
Мобильная версия