【问题标题】: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" alt="not found"> </button></span>
</div>

<div #parent></div>

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

【问题讨论】:

  • 请过去完整的 startComponent.ts 和 .html 代码。
  • 好的,我编辑了文本

标签: html angular typescript components parent-child


【解决方案1】:

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

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

子组件

constructor(private parentComp: StartComponent){

}

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

parentComp.addComponent();

更新

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

另一种解决方案

  1. 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。看控制台

  2. 手动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 有关。在本地尝试,应该没有警告
猜你喜欢
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
  • 2015-08-13
  • 2023-01-12
  • 1970-01-01
  • 2020-12-02
  • 2021-09-20
相关资源
最近更新 更多