在子组件中创建新的子组件
Posted
技术标签:
【中文标题】在子组件中创建新的子组件【英文标题】:Create new Child Component within a Child Component 【发布时间】:2018-09-25 20:39:26 【问题描述】:我有一个关于使用resolveComponentFactory
创建新组件的问题。首先有一个startComponent
(父组件),从这个组件有几个按钮,每个 btn 创建一个新的子组件。例如,现在我创建了一个“childComponent”,这也有效。但是现在我想在childComponent
中创建一个新的childComponent
,并且这个新组件应该有startComponent
作为父组件,而不是childComponent
本身。所以我需要一种方法来使用我的childComponent
从startComponent
调用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
可以吗?试图将注入器传递给viewContainerRef
的createComponent
方法。它没有帮助
有效!非常感谢您的努力和帮助 :) 但是有一件事:如果我编译代码,我总是会收到“警告:循环依赖:...”这有什么要担心的吗?即使有警告它也可以工作
@Kamui,很好。我认为,这与 StackBlitz 有关。在本地尝试,应该没有警告以上是关于在子组件中创建新的子组件的主要内容,如果未能解决你的问题,请参考以下文章