我正在创建一个通用的甘特图可视化组件。
我将显示周和任务的部分是通用的,但每行都有一个我想要动态的标题,例如,当显示每个用户的任务列表时,我想要放置一些用户数据和一些动作按钮,但当按项目显示任务时,我想显示项目数据和项目动作按钮。
我在此之后实施了一个解决方案:https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html
一切似乎都运行良好,我看到每个场景中的动作按钮加载方式不同,但不是用户或项目数据。此外,按钮上的console.log(this.data.name),我正确地看到控制台中的数据,但如果我尝试在模板{{ data.name }}
上打印,我什么也看不见。
我在控制台中看到以下错误:
错误:检查后表达式已更改。上一个值:' CD_INIT_VALUE'。当前值:'测试项目 - 任务3 &#39 ;.看起来这个视图是在其父级及其子级被脏检查后创建的。它是否已在变更检测钩子中创建?
我仔细检查了所有步骤,并且我正在执行与该教程相同的操作。
有人知道该教程是否过时了吗?
提前感谢您的帮助!
修改: 如果我将ngAfterViewInit更改为ngOnInit它一切正常...但根据教程我应该使用第一个。谁有人向我解释这个? : - )
答案 0 :(得分:13)
错误说明了一切:
看起来该视图是在其父级及其子级之后创建的 脏了检查。它是否已在变更检测钩子中创建?
您已动态创建组件(角度生命周期的“外部”),这意味着您需要手动控制更改检测。
这就是你需要做的事情:
1)为组件创建组件后触发detectChanges()
2)在处理detach()更改检测之前;
以下是我的指令动态创建组件的示例:
export class ValidationMessageDirective implements AfterViewInit, OnDestroy {
private validationMessageComponent: ComponentRef<ValidationMessageComponent> = null;
ngAfterViewInit(): void {
let factory = this.componentFactoryResolver.resolveComponentFactory(this.vmComp);
this.ngOnDestroy();
this.validationMessageComponent = this.viewContainer.createComponent(factory, null, this.viewContainer.injector);
this.validationMessageComponent.changeDetectorRef.detectChanges();
}
ngOnDestroy(): void {
if (this.validationMessageComponent) {
this.validationMessageComponent.changeDetectorRef.detach();
//this.validationMessageComponent.destroy();
}
}
constructor(
private viewContainer: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver,
@Inject(ValidationMessageComponent) private vmComp: Type<ValidationMessageComponent>
) {}
}