可观察数据更新时角度组件闪烁

问题描述 投票:0回答:1

我正在开发一个 Angular 组件(GestionAchatTpvGenerationProgressBarComponent),旨在根据来自 Observable 的数据显示进度条。该组件是独立的,并使用 OnPush 更改检测策略。进度条旨在反映通过 TPV(销售点终端)处理的某些购买的进度,并通过数据流 (achatTitreViaTpv) 进行更新。

但是,每次achatTitreViaTpv数据更新时,整个组件都会出现明显的“闪烁”或刷新,导致用户体验下降。我想了解为什么会发生这种行为以及如何避免或尽量减少这种行为。

这是该组件的简化代码:

@Component({
  selector: 'app-gestion-achat-tpv-generation-progress-bar',
  templateUrl: './gestion-achat-tpv-generation-progress-bar.component.html',
  styleUrls: ['./gestion-achat-tpv-generation-progress-bar.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    TranslateModule,
    NgIf,
    AsyncPipe,
    DecimalPipe
  ],
  standalone: true
})
export class GestionAchatTpvGenerationProgressBarComponent {
  @Select(GestionAchatTpvDetailState.recupereAchat) achatTitreViaTpv!: Observable<AchatTitreViaTpv>;
}

以及相关模板:

<div class="progress-bar-tpv-generation-container">
    <ng-container *ngIf="achatTitreViaTpv | async as achat">
        <div class="progress-bar-tpv-generation-container__titles-container">
            <!-- Display of progress and estimated remaining time -->
        </div>
        <div class="progress-bar-tpv-generation-container__progress-bar">
            <div class="progress-bar-tpv-generation-container__progress-bar--fill" [style.width]="(condition) + '%'"></div>
        </div>
    </ng-container>
</div>

我尝试过的:

  • 确保优化数据更新以避免不必要的重新发射。
  • 使用 OnPush 变更检测策略来最小化变更检查。

尽管进行了这些尝试,只要数据更新,闪烁就会持续存在。有人可以指出可能导致此行为的原因以及如何解决它吗?

angular typescript rxjs observable
1个回答
-1
投票

问题是Angular的变更检测系统仍然被多次触发。解决方案是使用角度信号。

变更组件的代码:

import { OnInit, WritableSignal, signal } from '@angular/core';

//(...)

export class TestComponent001Component implements OnInit {
  
    achatTitreViaTpv?: Observable<AchatTitreViaTpv>;
  
    achatTitreViaTpvSig: WritableSignal<AchatTitreViaTpv | undefined> = signal(undefined);
  
    ngOnInit(): void {
      if(this.achatTitreViaTpv) {
        this.achatTitreViaTpv.subscribe((data: AchatTitreViaTpv) => {
          //TODO: Check for changes in the line below:
          if(data.id != this.achatTitreViaTpvSig()?.id ?? 0) {
            this.achatTitreViaTpvSig.set(data);
          }
        });
    }
  } 
}

更改了 ng-container 的行:

<ng-container *ngIf="this.achatTitreViaTpvSig()">

我希望这有帮助。

编辑:当它不起作用时,你能显示更多代码吗?

© www.soinside.com 2019 - 2024. All rights reserved.