Javascript Angular2:以编程方式创建子组件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30830548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular2: Creating child components programmatically
提问by Waog
Question
题
How to create child components inside a parent component and display them in the view afterwards using Angular2? How to make sure the injectables are injected correctly into the child components?
如何在父组件内创建子组件,然后使用Angular2在视图中显示它们?如何确保可注射物正确注入到子组件中?
Example
例子
import {Component, View, bootstrap} from 'angular2/angular2';
import {ChildComponent} from './ChildComponent';
@Component({
selector: 'parent'
})
@View({
template: `
<div>
<h1>the children:</h1>
<!-- ??? three child views shall be inserted here ??? -->
</div>`,
directives: [ChildComponent]
})
class ParentComponent {
children: ChildComponent[];
constructor() {
// when creating the children, their constructors
// shall still be called with the injectables.
// E.g. constructor(childName:string, additionalInjectable:SomeInjectable)
children.push(new ChildComponent("Child A"));
children.push(new ChildComponent("Child B"));
children.push(new ChildComponent("Child C"));
// How to create the components correctly?
}
}
bootstrap(ParentComponent);
Edit
编辑
I found the DynamicComponentLoaderin the API docs preview. But I get the following error when following the example: There is no dynamic component directive at element 0
我DynamicComponentLoader在API 文档预览中找到了。但是在执行示例时出现以下错误:元素 0 处没有动态组件指令
采纳答案by TGH
This is generally not the approach I would take. Instead I would rely on databinding against an array that will render out more child components as objects are added to the backing array. Essentially child components wrapped in an ng-for
这通常不是我会采取的方法。相反,我将依赖于针对数组的数据绑定,当对象添加到支持数组时,该数组将呈现出更多的子组件。本质上是包裹在 ng-for 中的子组件
I have an example here that is similar in that it renders a dynamic list of children. Not 100% the same, but seems like the concept is still the same:
我在这里有一个类似的例子,它呈现了一个动态的孩子列表。不是 100% 相同,但似乎概念仍然相同:
http://www.syntaxsuccess.com/viewarticle/recursive-treeview-in-angular-2.0
http://www.syntaxsuccess.com/viewarticle/recursive-treeview-in-angular-2.0
回答by Anshul
Warning: DynamicComponentLoader has been deprecated in RC.4
警告:DynamicComponentLoader 在 RC.4 中已被弃用
In Angular 2.0, loadIntoLocationmethod of DynamicComponentLoaderserve this purpose of creating parent-child relationship. By using this approach you can dynamically create relationship between two components.
在角2.0loadIntoLocation的方法DynamicComponentLoader达到这个目的建立亲子关系的。通过使用这种方法,您可以动态地创建两个组件之间的关系。
Here is the sample code in which paperis my parent and bulletinis my child component.
这是示例代码,其中纸是我的父组件,公告是我的子组件。
paper.component.ts
paper.component.ts
import {Component,DynamicComponentLoader,ElementRef,Inject,OnInit} from 'angular2/core';
import { BulletinComponent } from './bulletin.component';
@Component({
selector: 'paper',
templateUrl: 'app/views/paper.html'
}
})
export class PaperComponent {
constructor(private dynamicComponentLoader:DynamicComponentLoader, private elementRef: ElementRef) {
}
ngOnInit(){
this.dynamicComponentLoader.loadIntoLocation(BulletinComponent, this.elementRef,'child');
}
}
bulletin.component.ts
公告.component.ts
import {Component} from 'angular2/core';
@Component({
selector: 'bulletin',
template: '<div>Hi!</div>'
}
})
export class BulletinComponent {}
paper.html
纸.html
<div>
<div #child></div>
</div>
Few things you needs to be take care of are mentioned in this answer
回答by Shivang Gupta
You should use ComponentFactoryResolver and ViewElementRef to add component at runtime.Let's have a look at below code.
您应该使用 ComponentFactoryResolver 和 ViewElementRef 在运行时添加组件。让我们看看下面的代码。
let factory = this.componentFactoryResolver.resolveComponentFactory(SpreadSheetComponent);
let res = this.viewContainerRef.createComponent(factory);
Put the above code inside your ngOnInit function and replace "SpreadSheetComponent" by your component name.
将上述代码放在 ngOnInit 函数中,并用您的组件名称替换“SpreadSheetComponent”。
Hope this will work.
希望这会奏效。
回答by xameeramir
Programmatically add components to DOM in Angular 2/4 app
在 Angular 2/4 应用程序中以编程方式将组件添加到 DOM
We need to use ngAfterContentInit()lifecycle method from AfterContentInit. It is called after the directive content has been fully initialized.
我们需要使用ngAfterContentInit()来自AfterContentInit. 在指令内容完全初始化后调用它。
In the parent-component.html, add the a divlike this:
在 中parent-component.html,div像这样添加 a :
<div #container> </div>
<div #container> </div>
The parent-component.tsfile looks like this:
该parent-component.ts文件如下所示:
class ParentComponent implements AfterContentInit {
@ViewChild("container", { read: ViewContainerRef }) divContainer
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
ngAfterContentInit() {
let childComponentFactory = this.componentFactoryResolver.resolveComponentFactory(childComponent);
this.divContainer.createComponent(childComponentFactory);
let childComponentRef = this.divContainer.createComponent(childComponentFactory);
childComponentRef.instance.someInputValue = "Assigned value";
}
}
Inside src\app\app.module.ts, add the following entry to the @NgModule()method parameters:
在里面src\app\app.module.ts,将以下条目添加到@NgModule()方法参数中:
entryComponents:[
childComponent
],
Notice that we're not accessing the div#containerusing the @ViewChild("container") divContainerapproach. We need it's reference instead of the nativeElement. We will access it as ViewContainerRef:
请注意,我们没有访问div#containerusing@ViewChild("container") divContainer方法。我们需要它的引用而不是nativeElement. 我们将访问它ViewContainerRef:
@ViewChild("container", {read: ViewContainerRef}) divContainer
@ViewChild("container", {read: ViewContainerRef}) divContainer
The ViewContainerRefhas a method called createComponent()which requires a component factory to be passed as a parameter. For the same, we need to inject a ComponentFactoryResolver. It has a method which basically loads a component.
该ViewContainerRef有一个称为方法createComponent()这需要一个单元工厂作为参数传递。同样,我们需要注入一个ComponentFactoryResolver. 它有一个基本上加载组件的方法。
回答by Shlomi Assaf
The right approach depends on the situation you're trying to solve.
正确的方法取决于您要解决的情况。
If the number of children is unknown then NgFor is the right approach.
If it is fixed, as you mentioned, 3 children, you can use the DynamicComponentLoaderto load them manually.
The benefits of manual loading is better control over the elements and a reference to them within the Parent (which can also be gained using templating...)
如果孩子的数量未知,那么 NgFor 是正确的方法。如果它是固定的,正如你提到的,3 个孩子,你可以使用DynamicComponentLoader手动加载它们。手动加载的好处是更好地控制元素和在父级中对它们的引用(也可以使用模板获得...)
If you need to populate the children with data, this can also be done via injection, the Parent is injected with a data object populating the children in place...
如果您需要用数据填充子级,这也可以通过注入来完成,父级被注入一个数据对象,在适当的位置填充子级......
Again, a lot of options. I have used 'DynamicComponentLoader' in my modal example, https://github.com/shlomiassaf/angular2-modal
再次,很多选择。我在我的模态示例中使用了“DynamicComponentLoader”,https://github.com/shlomiassaf/angular2-modal

