am3*_*am3 4 typescript angular2-template angular
我的目标是创建子组件并插入父组件模板.有一些例子可以做到这一点.但是,我在父组件中动态创建父组件模板(DOM元素),而大多数示例静态创建带有capture元素的模板.
这是代码
app.component
import {Component, ViewChild, ViewContainerRef, ComponentFactoryResolver} from '@angular/core';
import {NewChildComponent} from "./newChild.component";
@Component({
selector: 'app-main',
templateUrl: 'app.component.html'
})
export class AppComponent {
@ViewChild('captureElement', {read: ViewContainerRef})
captureElement: ViewContainerRef;
constructor (private componentFactoryResolver: ComponentFactoryResolver) {
var childComponent = this.componentFactoryResolver.resolveComponentFactory(NewChildComponent);
var myArea = document.getElementById('myArea');
var myRow = document.createElement("div");
myArea.appendChild(myRow);
//I want to add the capture element #myCapture as a child of myRow
//Add something like this <div #captureElement></div> programmatically through JS/TS
// How can I do this?
// I then create the component
this.parent.createComponent(NewChildComponent);
}
Run Code Online (Sandbox Code Playgroud)
app.component.html
<div id="myArea">
<!-- Static way of doing it -->
<!--<div #captureElement></div>-->
</div>
Run Code Online (Sandbox Code Playgroud)
#captureElement我想在父组件中动态创建它并使其成为子组件,而不是静态定义子组件的插入位置.
以下是我在提出这个问题之前提到的一系列问题
尝试了几件事
div元素#captureElement但不起作用. ViewContainerRef查找它.这也行不通.yur*_*zui 14
我们无法创建一个ViewContainerRef,ViewContainerRef只存在于视图中.
在2.3.0中,attachView介绍了允许您将更改检测附加到ApplicationRef.您可以创建一些类来封装您的逻辑,如:
export class HtmlContainer {
private attached: boolean = false;
private disposeFn: () => void;
constructor(
private hostElement: Element,
private appRef: ApplicationRef,
private componentFactoryResolver: ComponentFactoryResolver,
private injector: Injector) {
}
attach(component: Type<any>) : ComponentRef<any> {
if(this.attached) {
throw new Error('component has already been attached')
}
this.attached = true;
const childComponentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
let componentRef = childComponentFactory.create(this.injector);
this.appRef.attachView(componentRef.hostView);
this.disposeFn = () => {
this.appRef.detachView(componentRef.hostView);
componentRef.destroy();
};
this.hostElement.appendChild((componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0]);
return componentRef;
}
dispose() {
if(this.attached) {
this.disposeFn();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个班只是帮助
1)解析您的动态组件
this.componentFactoryResolver.resolveComponentFactory(component);
Run Code Online (Sandbox Code Playgroud)
2)然后通过调用编译组件 compFactory.create
3)之后通过上述调用注册changeDetector(componentRef.hostView扩展ChangeDetectorRef)appRef.attachView(否则更改检测将不适用于您的组件)
4)最后将组件的rootNode附加到host元素
this.hostElement.appendChild((componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0]);
Run Code Online (Sandbox Code Playgroud)
您可以按如下方式使用它:
@Component({
selector: 'my-app',
template: `<div id="myArea"></div> `,
entryComponents: [NewChildComponent]
})
export class AppComponent {
containers: HtmlContainer[] = [];
constructor(
private appRef: ApplicationRef,
private componentFactoryResolver: ComponentFactoryResolver,
private injector: Injector) {
}
ngOnInit() {
var myArea = document.getElementById('myArea');
var myRow = document.createElement("div");
myArea.appendChild(myRow);
this.addComponentToRow(NewChildComponent, myRow, 'test1');
this.addComponentToRow(NewChildComponent, myRow, 'test2');
}
addComponentToRow(component: Type<any>, row: HTMLElement, param: string) {
let container = new HtmlContainer(row, this.appRef, this.componentFactoryResolver, this.injector);
let componentRef = container.attach(component);
componentRef.instance.param1 = param;
this.containers.push(container);
}
ngOnDestroy() {
this.containers.forEach(container => container.dispose());
}
}
Run Code Online (Sandbox Code Playgroud)
也可以看看
| 归档时间: |
|
| 查看次数: |
4597 次 |
| 最近记录: |