Angular4动态加载组件适配ChangeDetectionStrategy.OnPush问题求助
嘿,这个场景我太熟悉了!之前在Angular 4项目里做动态加载组件+ChangeDetectionStrategy.OnPush策略的时候,也踩过一模一样的坑😅
虽然你已经确认传入的是全新的输入对象,但动态加载的组件因为创建方式特殊,有时候不会自动触发OnPush的变更检测逻辑。不过别担心,完全可以通过编程方式手动触发,下面是两种亲测有效的方案:
方案1:在动态组件内部手动标记变更检测
直接在你的动态组件里注入ChangeDetectorRef,然后在输入更新时主动标记需要检查的状态。
import { ChangeDetectorRef, Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'your-dynamic-comp', template: `<!-- 你的组件模板内容 -->`, changeDetection: ChangeDetectionStrategy.OnPush }) export class YourDynamicComponent { @Input() yourInputData: any; constructor(private cdr: ChangeDetectorRef) {} // 利用ngOnChanges钩子,输入引用变化时触发 ngOnChanges() { // 标记组件及其祖先为需要在下一次变更检测周期中检查 this.cdr.markForCheck(); // 如果需要立即更新视图,也可以用detectChanges() // this.cdr.detectChanges(); } }
小提示:markForCheck()和detectChanges()的区别:
markForCheck():只是标记状态,等待Angular的下一次全局变更检测周期执行更新,性能更优detectChanges():立即执行当前组件及其子组件的变更检测,适合需要实时刷新的场景
方案2:在父组件中直接触发动态组件的变更检测
因为动态组件是通过ViewContainerRef.createComponent()创建的,这个方法会返回一个ComponentRef实例,里面直接包含了该组件的changeDetectorRef对象,你可以在父组件更新输入后手动调用。
import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core'; import { YourDynamicComponent } from './your-dynamic.component'; @Component({ selector: 'app-parent', template: `<div #dynamicContainer></div>` }) export class ParentComponent { @ViewChild('dynamicContainer', { read: ViewContainerRef }) container: ViewContainerRef; private dynamicCompRef: any; constructor(private cfr: ComponentFactoryResolver) { // 初始化动态组件 const compFactory = this.cfr.resolveComponentFactory(YourDynamicComponent); this.dynamicCompRef = this.container.createComponent(compFactory); } // 更新动态组件输入的方法 updateDynamicComp(newData: any) { // 设置全新的输入对象(你已经确认是新引用) this.dynamicCompRef.instance.yourInputData = newData; // 手动触发动态组件的变更检测 this.dynamicCompRef.changeDetectorRef.markForCheck(); // 或者立即检测:this.dynamicCompRef.changeDetectorRef.detectChanges(); } }
额外验证点
再确认一下:你传入的输入对象确实是全新的引用(比如用{...oldData}或者Object.assign({}, oldData)创建的新对象),而不是修改了原有对象的属性——毕竟OnPush策略只对引用变化敏感,属性变化是不会触发的。
我当时就是用方案2解决的问题,完全适配Angular 4的版本,你可以试试看!
内容的提问来源于stack exchange,提问作者jredd
相关产品推荐
相关产品推荐

