如何在angular2中动态添加克隆节点(相当于cloneNode)

时间:2017-01-29 06:40:22

标签: angular dom clonenode ng-template

在Angular2中,我需要复制一个节点,而不是在某些情况下移动它。该节点具有angular2属性,因此cloneNode不起作用。我该怎么办?

*什么不起作用

    let el = <HTMLElement>document.getElementById(divId);
    if ((<HTMLElement>el.parentNode).id == 'itsMe')
        el = <HTMLElement>el.cloneNode(true);
    document.getElementById(anotherId).appendChild(el);

*什么可行,来自Angular2: Cloning component / HTML element and it's functionality

@Component({
  selector: 'my-app',
  template: `
    <template #temp>
        <h1 [ngStyle]="{background: 'green'}">Test</h1>
        <p *ngIf="bla">Im not visible</p>   
    </template>
    <template [ngTemplateOutlet]="temp"></template>
    <template [ngTemplateOutlet]="temp"></template>
    `
})

export class AppComponent {
    bla: boolean = false;
    @ContentChild('temp') testEl: any;
} 

但是如何动态添加模板?

1 个答案:

答案 0 :(得分:5)

让我们使用以下标记进行说明:

<p>Paragraph One</p>
<p>Paragraph Two</p>   <!-- Let's try to clone this guy -->
<p>Paragraph Three</p>

选项1 - 手动将元素包装在<template>标记内

这基本上就是您所做的,而不是使用ngTemplateOutlet打印出模板,在组件的类中获取对它的引用,并使用createEmbeddedView()强制插入。

@Component({
    selector: 'my-app',
    template: `
      <p>Paragraph One</p>
      <template #clone>
        <p>Paragraph Two</p>
      </template>
      <p>Paragraph Three</p>

      <button (click)="cloneTemplate()">Clone Template</button>

      <div #container></div>
    `
})
export class AppComponent{
    // What to clone
    @ViewChild('clone') template;

    // Where to insert the cloned content
    @ViewChild('container', {read:ViewContainerRef}) container;

    constructor(private resolver:ComponentFactoryResolver){}

    cloneTemplate(){
        this.container.createEmbeddedView(this.template);
    }
}

在此示例中,我将“clone”插入标记中的特定位置(<div #container></div>),但您也可以将其附加到当前组件模板的底部。

另请注意,原始<p>Paragraph Two</p>不再可见。

选项2 - 使用结构指令

如果您想要在当前位置克隆元素 ,最后会:

<p>Paragraph One</p>
<p>Paragraph Two</p>   <!-- Original paragraph -->
<p>Paragraph Two</p>   <!-- Cloned paragraph   -->
<p>Paragraph Three</p>

然后你可以创建一个结构指令*clone并将其应用于要克隆的段落,如下所示:

<p>Paragraph One</p>
<p *clone>Paragraph Two</p>
<p>Paragraph Three</p>

有趣的是,结构指令的作用是将它应用的元素包装在<template>标记内。与我们在选项1中所做的非常类似,只有在这种情况下,我们对克隆打印出来的位置没有控制权(它们将显示在原始段落的位置)。

这基本上会复制*ngFor的行为,所以它可能不是很有用。此外,从您对yurzui的评论看来,这不是您想要的。