实战(原来写法)
<app-edit-classify [classifyOpt]="classifyOpt" [showClassifyModal]="showClassifyModal" [addClassifyType]="addClassifyType" [classifyDetail]="classifyDetail" (changeClassifyModal)="changeClassifyModal($event)"></app-edit-classify>
动态组件写法(具体解释看上头的链接哈)
constructor(
private _resolver: ComponentFactoryResolver,
) { }
/**
* @desc 创建组件
* @param {string} type - 组件名
*/
public createComponent(type: string): any {
// 清空容器
this.componentContainer.clear();
// input 相当于@input()
// origin相当于子组件的值
// to相当于父组件传给子组件的值
const componentObj = {
editClassifyDialog: {
instance: EditClassifyComponent,
input: [
{
origin: 'showClassifyModal',
to: this.showClassifyModal
},
{
origin: 'classifyOpt',
to: this.classifyOpt
},
{
origin: 'addClassifyType',
to: this.addClassifyType
},
{
origin: 'classifyDetail',
to: this.classifyDetail
}
],
output: [
{
origin: 'changeClassifyModal',
callFn: this.changeClassifyModal
}
]
},
}[type];
const factory = this.resolver.resolveComponentFactory(componentObj.instance);
const componentRef = this.componentContainer.createComponent(factory);
// @Input 输入属性处理
if (componentObj['input'].length) {
componentObj['input'].forEach((item: any) => {
componentRef.instance[item.origin] = item.to;
});
}
// @Output 输出方法处理
if (componentObj['output'].length) {
componentObj['output'].forEach((item: any) => {
componentRef.instance[item.origin].subscribe(($event: any) => {
item.callFn.bind(this)($event); // bind解决this指向问题
});
});
}
// 返回组件实例
return componentRef.instance;
}
public addNewClassify(classifyType: string): void {
// 动态创建组件
this.createComponent('editClassifyDialog').init();
}
tips: 如果使用form表单赋值没生效时 考虑使用脏检查
this._cdrSer.detach();
this.classifyForm.patchValue(this.classifyDetail);
this._cdrSer.detectChanges();
tips: 然后由于不走onchanges方法 导致视图不会动态渲染 所以有好多的问题