gpt4 book ai didi

javascript - Angular递归创建动态组件

转载 作者:行者123 更新时间:2023-11-30 14:35:07 24 4
gpt4 key购买 nike

我正在尝试构建一个基于配置的动态组件。该组件将递归读取配置并创建组件。发现ngAfterViewInit()方法只会被调用两次。

@Component({
selector: "dynamic-container-component",
template: `
<div #container
draggable="true"
(dragstart)="dragstart($event)"
(drop)="drop($event)"
(dragover)="dragover($event)"
style="border: 1px solid; min-height: 30px"></div>
`
})
export default class DynamicContainerComponent {

@Input()
dynamicConfig: DynamicConfig;

@ViewChild("container", {read: ElementRef})
private elementRef: ElementRef;

private isContainer: boolean;
private componentRef: ComponentRef<any>;
private componentRefs: ComponentRef<any>[] = [];

constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private injector: Injector,
private viewContainer: ViewContainerRef,
private render: Renderer2
){
console.log("running");
}

ngAfterViewInit(){

if (this.dynamicConfig){
console.log(this.dynamicConfig)
if (this.dynamicConfig.getType() == ComponentType.INPUT){
this.isContainer = false;
let componetFactory: ComponentFactory<InputComponent> =
this.componentFactoryResolver.resolveComponentFactory(InputComponent);
this.componentRef = this.viewContainer.createComponent(componetFactory);
this.render.appendChild(this.elementRef.nativeElement, this.componentRef.location.nativeElement);
}else {
this.isContainer = true;
let items: DynamicConfig[] = this.dynamicConfig.getItems();
if (items){
for (var i=0; i<items.length; i++){
let item: DynamicConfig = items[i];
let componetFactory: ComponentFactory<DynamicContainerComponent> =
this.componentFactoryResolver.resolveComponentFactory(DynamicContainerComponent);
let componentRef: ComponentRef<DynamicContainerComponent> =
this.viewContainer.createComponent(componetFactory);
componentRef.instance.dynamicConfig = item;
this.componentRefs.push(componentRef);
this.render.appendChild(this.elementRef.nativeElement, componentRef.location.nativeElement);
}
}
}
}else {
console.log("config does not exist");
}

}

dragstart(event){
debugger;
}

drop(event){
debugger;
}

dragover(event){
debugger;
event.preventDefault();
}


}

该组件将由其他组件通过以下代码创建。如果动态组件将通过 componentFactoryResolver 创建另一个动态组件。

    var configJson = {
type: ComponentType.CONTAINER,
items: [
{
type: ComponentType.CONTAINER,
items: [{
type: ComponentType.CONTAINER,
items: [{
type: ComponentType.CONTAINER,
items: [{
type: ComponentType.INPUT
}]
}]
}]
}
]
}

this.config = new DynamicConfig();
this.config.assign(configJson);
console.log(this.config);

更新我在 github 中发现了类似的问题:https://github.com/angular/angular/issues/10762

我做了一些其他人建议的事情。但我认为这只是一个肮脏的修复。

ngAfterViewInit(){
setTimeout(function(){
if (this.dynamicConfig){
console.log(this.dynamicConfig)
if (this.dynamicConfig.getType() == ComponentType.INPUT){
this.isContainer = false;
let componetFactory: ComponentFactory<InputComponent> =
this.componentFactoryResolver.resolveComponentFactory(InputComponent);
this.componentRef = this.viewContainer.createComponent(componetFactory);
this.render.appendChild(this.elementRef.nativeElement, this.componentRef.location.nativeElement);
}else {
this.isContainer = true;
let items: DynamicConfig[] = this.dynamicConfig.getItems();
if (items){
for (var i=0; i<items.length; i++){
let item: DynamicConfig = items[i];
let componetFactory: ComponentFactory<DynamicContainerComponent> =
this.componentFactoryResolver.resolveComponentFactory(DynamicContainerComponent);
let componentRef: ComponentRef<DynamicContainerComponent> =
this.viewContainer.createComponent(componetFactory);
componentRef.instance.dynamicConfig = item;
this.componentRefs.push(componentRef);
this.render.appendChild(this.elementRef.nativeElement, componentRef.location.nativeElement);
}
}
}
}else {
console.log("config does not exist");
}
}.bind(this))
}

最佳答案

当您创建动态组件时,angular 几乎已完成变更检测周期。

这样你可以运行:

componentRef.changeDetectorRef.detectChanges()

注意:setTimeout 具有类似的效果,但会在整个应用程序上触发更改检测周期

将生命周期 Hook 重命名为ngOnInit

此外,您还向动态组件传递了错误的输入:

let item: DynamicConfig = items[i];
^^^^^^^^^^^^^
but it is not DynamicConfig instance but rather plain object
...
componentRef.instance.dynamicConfig = item;

应该是:

let item: any = items[i];
const config = new DynamicConfig();
config.assign(item);
componentRef.instance.dynamicConfig = config;

Ng-run Example

关于javascript - Angular递归创建动态组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50539133/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com