Angular 2:在创建组件时动态插入捕获元素(动态)

前端之家收集整理的这篇文章主要介绍了Angular 2:在创建组件时动态插入捕获元素(动态)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的目标是创建子组件并插入父组件模板.有一些例子可以做到这一点.但是,我在父组件中动态创建父组件模板(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);

 }

app.component.html

<div id="myArea">
  <!-- Static way of doing it -->
  <!--<div #captureElement></div>-->      
</div>

我想在父组件中动态创建它并使其成为子组件,而不是在将要插入子组件的#captureElement中静态定义.

以下是我在提出这个问题之前提到的一系列问题

> Angular2: Insert a dynamic component as child of a container in the DOM
> How to place a dynamic component in a container
> Angular 2 dynamic tabs with user-click chosen components

尝试过几件事

>尝试使用#captureElement创建一个div元素
以编程方式属性,但不起作用.
>尝试以编程方式创建随机元素,并使用ViewContainerRef来查找它.这也行不通.

我们无法创建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();
    }
  }
}

这个班只是帮助

1)解析您的动态组件

this.componentFactoryResolver.resolveComponentFactory(component);

2)然后通过调用compFactory.create来编译组件

3)之后通过调用上面提到的appRef.attachView来注册其changeDetector(componentRef.hostView扩展ChangeDetectorRef)(否则更改检测将不适用于您的组件)

4)最后将组件的rootNode附加到host元素

this.hostElement.appendChild((componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0]);

您可以按如下方式使用它:

@Component({
  selector: 'my-app',template: `<div id="myArea"></div> `,entryComponents: [NewChildComponent]
})
export class AppComponent {
  containers: HtmlContainer[] = [];

  constructor(
    private appRef: ApplicationRef,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,'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());
  }
}

Plunker Example

也可以看看

> Angular2 – Component into dynamicaly created element
> Angular2 Dynamic Component Injection in Root
> https://github.com/angular/material2/blob/2.0.0-beta.1/src/lib/core/portal/dom-portal-host.ts#L30-L86(你可以在这里找到角度< 2.3.0的后备)

猜你在找的Angularjs相关文章