在子组件中创建新的子组件

Posted

技术标签:

【中文标题】在子组件中创建新的子组件【英文标题】:Create new Child Component within a Child Component 【发布时间】:2018-09-25 20:39:26 【问题描述】:

我有一个关于使用resolveComponentFactory 创建新组件的问题。首先有一个startComponent(父组件),从这个组件有几个按钮,每个 btn 创建一个新的子组件。例如,现在我创建了一个“childComponent”,这也有效。但是现在我想在childComponent 中创建一个新的childComponent,并且这个新组件应该有startComponent 作为父组件,而不是childComponent 本身。所以我需要一种方法来使用我的childComponentstartComponent 调用addComponent() 方法。

这是我目前的做法:

startComponent.ts:

import 
Component, OnInit, ViewChild,
ComponentFactoryResolver,
ViewContainerRef
 from '@angular/core';

Import  childComponent  from '../childComponent/child.component';
import  DataService  from '../data.service';

@Component(
selector: 'app-start',
templateUrl: './start.component.html',
styleUrls: ['./start.component.css']
)


export class startComponent implements OnInit 
@ViewChild('parent',  read: ViewContainerRef ) container: ViewContainerRef;

constructor(private dataService: DataService, private componentFactoryResolver: ComponentFactoryResolver)

ngOnInit()

addComponent()

let componentFactory = this.componentFactoryResolver.resolveComponentFactory(childComponent);

let component = this.container.createComponent(componentFactory);
// next Line i save the reference of the "childComponent" to a Service
// so the "childComponent" can get it and destroy himself if wanted
this.createComponentService.setReference(component, type);


startComponent.html

<div>
<span matTooltip="Select"><button (click)="addComponent()" class="btn">
<img class="img" src="./assets/StartIcons/childCreate-icon.png" > </button></span>
</div>

<div #parent></div>

如果我想用我的childComponent 创建一个childComponent,它确实有效,但startComponent 不是父组件。 希望您能理解我的问题,否则我可以尝试再次解释。

【问题讨论】:

请过去完整的 startComponent.ts 和 .html 代码。 好的,我编辑了文本 【参考方案1】:

但现在我想在 childComponent 和这个新组件的 startComponent 应为 父组件,而不是 childComponent 本身。所以我需要一种方法 用我的从 startComponent 调用 addComponent() 方法 子组件。

因此,在childComponent 中,您应该引用parentComponent(StartComponent)。您可以通过注入新添加的 childComponent 来获取它:

子组件

constructor(private parentComp: StartComponent)


当您参考它时,您可以访问parent 的属性和方法,并且在childComponent 内可以轻松调用addComponent(),如下所示:

parentComp.addComponent();

更新

有趣的、动态创建的组件在injector 中没有父组件。所以,它不能注入父StartComponent

另一种解决方案

    StartComponet设置子组件的父属性:

    ngOnInit() 
       this.comps.clear();
       let aComponentFactory = 
       this.componentFactoryResolver.resolveComponentFactory(this.compArr[0]);
       let aComponentRef = this.comps.createComponent(aComponentFactory);
    
       (<AComponent>aComponentRef.instance).name = 'A name';
       (<AComponent>aComponentRef.instance).parent = this;
     
    

    StackBlitz Demo。看控制台

    手动inject子组件中的父组件:

    constructor(public injector: Injector ) 
        console.log('child injector', injector);
        this.parent = injector.get(AppComponent);
    
    
    ngOnInit() 
       console.log('parent is here', this.parent);
       this.parent.test();
    
    

    StackBlitz Demo。看控制台

【讨论】:

试过但它给了我一个错误:无法解析 childComponent 的所有参数:([object Object],[object Object],?)。 '构造函数(私有dataService:DataService,私有componentFactoryResolver:ComponentFactoryResolver,私有startComponent:startComponent)' @Kamui,哦。真的。。很奇怪。会检查 @Kamui,更新了答案。 @yurzui,在contructor父组件中动态创建的子组件不能inject可以吗?试图将注入器传递给viewContainerRefcreateComponent 方法。它没有帮助 有效!非常感谢您的努力和帮助 :) 但是有一件事:如果我编译代码,我总是会收到“警告:循环依赖:...”这有什么要担心的吗?即使有警告它也可以工作 @Kamui,很好。我认为,这与 StackBlitz 有关。在本地尝试,应该没有警告

以上是关于在子组件中创建新的子组件的主要内容,如果未能解决你的问题,请参考以下文章

Vue中,父组件向子组件传值

text 在子文件夹中创建组件

匕首:访问项目在子组件中创建了两个级别

Jest快照测试 - 在componentDidMount()中创建新对象时发生错误

在 Gitlab 中创建新的子组时出现 500 错误

iOS组件库创建