angular - 将整个应用程序标记为脏并强制更改检测

标签 angular angular-changedetection

让我们想象一个应用程序

  • 所有组件(包括 app.component)都是 onPush .

  • 我如何调用函数 forceAppWideChangeDetection()例如app.component这将确保在应用程序的每个组件中运行 changeDetection。
    我想我必须遍历组件的内部树并在每个组件上调用 markForCheck。
    如何才能做到这一点?
    请注意
  • 我的应用程序仍在 viewEngine 上。如果这可能与我有关。
  • 我问这个的原因是:当 UI 中的语言从 lang-a 更改为 lang-b 时。几乎每个组件都需要一个 changeDetection 来更新显示的文本语言。目前我们有自己的@Input()为此,它遍历整个组件树并强制组件重新呈现为“输入属性已更改”。我个人不喜欢这种方法,正在寻找更简单的解决方案。所以你可以看到这个昂贵的方法 forceAppWideChangeDetection()只需在语言更改时运行。
  • 最佳答案

    除非有我不知道的开箱即用解决方案,否则您可以使用服务和基类:

    @Injectable({ providedIn: 'root' })
    export class ChangeDetectionTriggerService {
      readonly trigger$ = new Subject<void>();
    }
    
    然后是基础组件:
    @Directive()
    export class BaseComponent implements OnDestroy {
    
      readonly onDestroy$ = new Subject<void>();
    
      ngOnDestroy(): void {
        this.onDestroy$.next();
      }
    
    }
    
    @Directive() // https://angular.io/guide/migration-undecorated-classes
    export class BaseChangeDetectionComponent implements OnInit extends BaseComponent {
    
      constructor(private changeDetectorRef: ChangeDetectorRef,
                  private changeDetectionTriggerService: ChangeDetectionTriggerService) {
        super();
      }
    
      ngOnInit(): void {
        this.changeDetectionSub = changeDetectionTriggerService.trigger$
          .pipe(takeUntil(this.onDestroy$))
          .subscribe(() => this.changeDetectorRef.markForCheck());
      }
    
    }
    
    在目标组件中的用法:
    @Component(/** ... **/)
    export class MyComponent extends BaseChangeDetectionComponent {
    
      constructor(private changeDetectorRef: ChangeDetectorRef,
                  private changeDetectionTriggerService: ChangeDetectionTriggerService) {
        super(this.changeDetectorRef, this.changeDetectionTriggerService);
      }
    
    }
    
    然后通过简单地在主题中发射来在任何地方使用它:
    changeDetectionTriggerService.trigger$.next();
    
    这可能会奏效。但把它作为最后的手段。希望有一个更简单和优雅的解决方案。

    关于angular - 将整个应用程序标记为脏并强制更改检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68033767/

    相关文章:

    Angular 服务库

    angular - RxJs 限制订阅调用的数量

    Angular - 不纯管道与函数

    angular - 如何避免使用 View 中的方法触发组件中的更改检测?

    Angular 性能 - OnPush 增加循环次数

    javascript - 无法从手机加载Ionic项目

    angular - 如何从可观察对象数组中返回可观察对象

    angular - 如何在 angular 7 中创建可选的路由器参数

    angular - store.select subscribe 中的更改检测需要 markForCheck。为什么?

    棱 Angular 分明。为什么调用 markForCheck() 结果查看更新