У меня есть простой список в представлении с жестко запрограммированными данными в контроллере:
errorcount.component.html
...
<tr *ngFor = "let errorcounter of errorCounterList">
<td>{{errorcounter.date}}</td>
<td style = "text-align:right;">{{errorcounter.count}}</td>
</tr>
....
errorcount.component.ts
import { Component, OnInit, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';
export interface ErrorCounter {
id: number,
error_id: number,
date: string,
count: number
};
@Component({
selector: 'app-errorcount',
templateUrl: './errorcount.component.html',
styleUrls: ['./errorcount.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ErrorcountComponent implements OnInit {
errorCounterList: ErrorCounter[];
constructor(private ref: ChangeDetectorRef) {
this.errorCounterList = [
{ id: 1, error_id: 1, date: '20230101', count: 201 },
{ id: 2, error_id: 2, date: '20230102', count: 321 },
{ id: 3, error_id: 3, date: '20230103', count: 431 },
{ id: 4, error_id: 1, date: '20230104', count: 541 },
{ id: 5, error_id: 2, date: '20230105', count: 651 },
{ id: 6, error_id: 3, date: '20230106', count: 561 },
{ id: 7, error_id: 1, date: '20230107', count: 471 },
{ id: 8, error_id: 2, date: '20230108', count: 381 },
{ id: 9, error_id: 3, date: '20230109', count: 282 },
{ id: 10, error_id: 1, date: '20230110', count: 184 },
];
}
ngOnInit(): void {
this.ref.detectChanges();
}
filterCounters(id: number) {
this.errorCounterList = this.errorCounterList.filter(f => f.error_id == id);
this.ref.markForCheck();
}
}
Я вызываю filterCounters(), и отладчик показывает отфильтрованный список, но detectChanges не изменяет элементы в представлении.
Любая помощь заставит меня снова спать.
У меня работает, смотрите stackblitz.com/edit/angular-kazmjn?file=src%2Fmain.ts, без использования ChangeDetectorRef
проблема живет где-то еще
Куда звонить filterCounters
?
Привет, Леонмейн. Я думаю, что моя проблема в том, откуда я вызываю filterCounters. у меня есть одно представление с двумя компонентами в карточках материалов, пытающихся обновить друг друга. Я наткнулся на угловые зоны. Постараюсь реализовать: mokkapps.de/blog/…
Я готов воспроизвести ваше приложение по следующей ссылке stackblitz:
https://stackblitz.com/edit/my-angular-project-wdllee?file=app/login/login.component.ts
И работает отлично, вам нужно вызвать функцию фильтра:
ngOnInit(): void {
this.ref.detectChanges();
this.filterCounters(1); // => You need call your function
}
Вам не нужно «ChangeDetectionStrategy.OnPush
», лучше, если вы вызываете свою функцию только тогда, когда вам нужно обновить свой вид.
Пожалуйста, прочитайте эту статью:
Кому это может помочь, единственный способ заставить это работать - использовать LocalStorage:
ngOnInit(): void {
localStorage.setItem('errorCounterList', JSON.stringify(this.errorCounterList));
}
filterCounterList(id: number) {
localStorage.removeItem('errorCounterList');localStorage.setItem('errorCounterList',JSON.stringify(this.errorCounterList.filter(f => f.error_id == id)));
}
getCounterList() {
this.errorCounterList = JSON.parse(localStorage.getItem('errorCounterList') ?? '');
return this.errorCounterList;
}
Это решило мою имитацию проблемы, но не всегда подходит в качестве решения.
Попробуйте использовать
detectChanges()
вместоmarkForCheck()
, так как вы используете обнаружение измененийOnPush
, и оно не сработает, пока переменные, привязанные к данным, не будут изменены. Этот поток SO может быть полезен: stackoverflow.com/a/41364469/1331040