#javascript #arrays #angular #dom #service
#javascript #массивы #угловатый #дом #Обслуживание
Вопрос:
Я столкнулся с проблемой, связанной с манипуляцией DOM в angular. Я определил один массив с именем colors в своем компоненте, а затем вызываю метод service и получаю данные о цветах с сервера, а затем присваиваю их массиву colors внутри метода subscribe. В HTML-шаблоне, использующем цикл *ngFor, я отображаю данные массива цветов. Теперь я хочу добавить некоторый динамический класс или стиль к элементам HTML, и для этого я использую ElementRef для доступа к этому элементу, но я не могу получить к нему доступ, потому что массив цветов изначально не определен. Теперь позвольте мне приложить код…
@Component({
selector: 'app',
template: "<div><li class="color" *ngFor="let color of colors">{{color}}</li></div>",
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewInit {
colors:any;
constructor(private elementRef:ElementRef, private renderer:Renderer2) {}
ngOnInit():void {
setTimeout(() => {
this.colors = ['red', 'yellow', 'green'];
}, 1000);
}
ngAfterViewInit():void {
const color = this.elementRef.nativeElement.querySelectorAll('.color');
console.log(color);
}
}
Здесь я использую функцию setTimeout в этом коде, которая ведет себя как служба, потому что службе требуется некоторое время для получения данных с сервера, но в моем коде я использую service .
Теперь, если я открываю консоль в инструментах разработчика, я получаю NodeList [] это означает, что я не могу получить доступ к элементу DOM. Я знаю проблему, я не могу получить доступ к элементу DOM, потому что мой код для доступа к элементу DOM выполняется до назначения данных массиву цветов, а по умолчанию или изначально массив цветов не определен или пуст. Вот почему я получаю NodeList [] в консоли. Но я не в состоянии понять, как решить эту проблему?.
Заранее благодарю.
Ответ №1:
Вам нужно ngAfterViewCHecked
. Это будет выполняться каждый раз, когда Angular завершит выполнение обнаружения изменений в компоненте и его дочерних элементах
Во-вторых, есть ошибка template
. Если вы используете все двойные кавычки "
, это приведет к завершению строки. Вам не нужно использовать одинарные и двойные кавычки для всех подобных атрибутов
'<div><li class="color" *ngFor="let color of colors">{{color}}</li></div>'
Комментарии:
1. да, но проблема с ngAfterViewChecked заключается в том, что он каждый раз запускает весь код внутри этого и делает приложение запаздывающим или медленным, например: проверьте эту ссылку на код: stackblitz.com/edit/angular-ivy-qsy5ma?file=src/app /…
Ответ №2:
Это происходит потому ngAfterViewInit
, что завершаются вызовы до истечения установленного вами тайм-аута ngOnInit
.
Я бы выбрал ViewChildren
более надежный подход.
Вот один из примеров:
@Component({
selector: "my-app",
template: `
<ul>
<li #color *ngFor="let color of (colors$ | async)">{{ color }}</li>
</ul>
`,
styles: []
})
export class AppComponent implements OnDestroy, AfterViewInit {
@ViewChildren("color") colors: QueryList<ElementRef<HTMLLIElement>>;
colors$: Observable<string[]> = of(["red", "green", "blue"]).pipe(
delay(3000)
);
private colorsSubscription = Subscription.EMPTY;
ngAfterViewInit(): void {
this.colors.changes.subscribe(list => {
list.forEach(element => {
console.log(element.nativeElement);
});
});
}
ngOnDestroy(): void {
this.colorsSubscription.unsubscribe();
}
}
То, что мы делаем в этом примере, это:
- Инициализация
colors$
для запуска строкового массива через 3 секунды - Подписка на
colors$
сAsyncPipe
помощью и отображение цветов - Настройка
ViewChildren
запроса для всех элементов со#color
ссылкой на шаблон - Подписка на
QueryList
изменения (добавления / удаления и т.д.) и соответствующие действия
Вы можете найти полный пример в этом стекблите
Комментарии:
1. да, но если я пытаюсь получить доступ к первому элементу, используя этот код внутри метода ngAfterViewInit. код: console.log(this.colors. toArray[0].nativeElement); Я не могу получить к нему доступ, тогда как я добавлю новый стиль к этому элементу.
2. Это связано с тем, что вы не можете получить доступ к списку в разделе изменения по индексу. Вы можете, например, перебирать элементы, используя
forEach
. Я обновил пример, чтобы показать это.