Angular Пользовательский интерфейс не обновляется после срабатывания наблюдаемой подписки - PullRequest
1 голос
/ 07 мая 2020

У меня есть страница angular, на которой используется наблюдаемый параметр службы. Однако, когда это наблюдаемое обновление, страница не обновляется, чтобы соответствовать.

Я попытался сохранить результат наблюдаемого в плоском значении или изменить логическое значение для настройки пользовательского интерфейса, но, похоже, ни один из них не имеет никакого эффекта .

Регистрация наблюдаемого подтверждает, что оно обновляется правильно, и при повторном переходе на страницу отображается новое значение.

Другие условные обновления пользовательского интерфейса правильно изменяют страницу, только одно ниже ( *ngIf="(entries$ | async), else loading") вызывает эту проблему.

component.ts

export class EncyclopediaHomeComponent implements OnInit {
  entries$: Observable<EncyclopediaEntry[]>;
  categories$: Observable<string[]>;
  entry$: Observable<EncyclopediaEntry>;
  entry: EncyclopediaEntry;
  isEditing: boolean;

  constructor(private route: ActivatedRoute, private encyService: EncyclopediaService) {
    this.entries$ = encyService.entries$;
    this.categories$ = encyService.categories$;

    this.entries$.subscribe(es => {
      console.log(es);
    });

    route.url.subscribe(url => this.isEditing = url.some(x => x.path == 'edit'));
    this.entry$ = route.params.pipe(
      switchMap(pars => pars.id ? encyService.getEntry(pars.id) : of(null)),
    );
    this.entry$.subscribe(entry => this.entry = entry);
  }

  ngOnInit(): void {
  }

  updateEntry(entry: EncyclopediaEntry) {
    this.encyService.updateEntry(entry.id, entry);
  }
}

component. html

<div class="encyclopedia-container">
    <ng-container *ngIf="(entries$ | async), else loading">
        <app-enc-list [entries]="entries$ | async"
            [selectedId]="entry ? entry.id : null"></app-enc-list>

        <ng-container *ngIf="entry">
            <app-enc-info *ngIf="!isEditing, else editTemplate"
                [entry]="entry$ | async"></app-enc-info>

            <ng-template #editTemplate>
                <app-enc-edit [entry]="entry$ | async" [categories]="categories$ | async"
                    (save)="updateEntry($event)"></app-enc-edit>
            </ng-template>
        </ng-container>
    </ng-container>
    <ng-template #loading>
        <mat-progress-bar mode="indeterminate"></mat-progress-bar>
        <br>
        <p>Loading Encyclopedia...</p>
    </ng-template>
</div>

редактировать: service.ts

export class EncyclopediaService {
  entriesSubject = new ReplaySubject<EncyclopediaEntry[]>();
  entries$ = this.entriesSubject.asObservable();
  private _entries: EncyclopediaEntry[];

  constructor(private file: FileService) {
    file.readFromFile(this.projectName+'Encyclopedia').subscribe((es: string) => {
      this._entries = JSON.parse(es);
      this.entriesSubject.next(this._entries);
      this.entries$.subscribe(es => this.file.writeToFile(this.projectName+'Encyclopedia', JSON.stringify(es)));
    });
  }
  .
  .
  .
}

1 Ответ

2 голосов
/ 07 мая 2020

Похоже, компонент не видит изменений. Я не знаю почему, потому что | asyn c выполнит эту работу.

, но чтобы исправить это, вы можете использовать ChangeDetector:


constructor(
   private route: ActivatedRoute,  
   private encyService: EncyclopediaService
   private changeDetectorRef: ChangeDetectorRef,
) {
    this.entries$ = encyService.entries$;
    this.categories$ = encyService.categories$;

    this.entries$.subscribe(es => {
      // setTimeout need to run without troubles with ng changes detector
      setTimeout(_=>{this.changeDetectorRef.detectChanges()},0);
      ...
    });

или вы можете использовать markforCheck, как описано там .

...