Почему мой ChangeDetectorRef не обновляет список в представлении?

У меня есть простой список в представлении с жестко запрограммированными данными в контроллере:

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 не изменяет элементы в представлении.

Любая помощь заставит меня снова спать.

Попробуйте использовать detectChanges() вместо markForCheck(), так как вы используете обнаружение изменений OnPush, и оно не сработает, пока переменные, привязанные к данным, не будут изменены. Этот поток SO может быть полезен: stackoverflow.com/a/41364469/1331040

Harun Yilmaz 30.03.2023 16:45

У меня работает, смотрите stackblitz.com/edit/angular-kazmjn?file=src%2Fmain.ts, без использования ChangeDetectorRef проблема живет где-то еще

Andres2142 30.03.2023 16:56

Куда звонить filterCounters?

leonmain 30.03.2023 17:58

Привет, Леонмейн. Я думаю, что моя проблема в том, откуда я вызываю filterCounters. у меня есть одно представление с двумя компонентами в карточках материалов, пытающихся обновить друг друга. Я наткнулся на угловые зоны. Постараюсь реализовать: mokkapps.de/blog/…

Aleksander Spacca 31.03.2023 20:39
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
4
74
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я готов воспроизвести ваше приложение по следующей ссылке 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», лучше, если вы вызываете свою функцию только тогда, когда вам нужно обновить свой вид.

Пожалуйста, прочитайте эту статью:

https://stackoverflow.com/a/53426605/9420442

Ответ принят как подходящий

Кому это может помочь, единственный способ заставить это работать - использовать 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;
}

Это решило мою имитацию проблемы, но не всегда подходит в качестве решения.

Другие вопросы по теме