【问题标题】:How to dynamically add a cloned node in angular2 (equivalent to cloneNode)如何在angular2中动态添加克隆节点(相当于cloneNode)
【发布时间】:2017-06-14 13:44:25
【问题描述】:

在 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;
} 

但是如何动态添加模板呢?

【问题讨论】:

  • 你试过用ngFor吗?
  • 有什么用?我想动态地做到这一点

标签: angular dom clonenode ng-template


【解决方案1】:

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

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

选项 1 - 手动将要克隆的元素包装在 &lt;template&gt; 标记内

这基本上就是你所做的,只是不是用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);
    }
}

在本例中,我将“克隆”插入到标记中的特定位置 (&lt;div #container&gt;&lt;/div&gt;),但您也可以将其附加到当前组件模板的底部。

另请注意,原来的&lt;p&gt;Paragraph Two&lt;/p&gt; 不再可见。

选项 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>

有趣的是,结构指令所做的是将它应用到的元素包装在 &lt;template&gt; 标记内。与我们在选项 1 中所做的非常相似,只是在这种情况下,我们无法控制打印副本的位置(它们将出现在原始段落所在的位置)。

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

【讨论】:

  • 我正在尝试选项 1,我会说你在 @ViewChild('template') 中有一个错误,它应该是 'clone'(或者至少对我有用)。有没有一种方法可以动态定义注入克隆模板的位置?有点像document.getElementById.createEmbeddedView?
  • @Gerard。好吧,您确实需要一个锚点来插入克隆的模板。 AFAIK,在 @ViewChild(selector) 装饰器中,selector 可以是指令/组件或模板变量,就像我的示例中一样。文档不清楚您是否可以使用其他类型的选择器。也许尝试一个类选择器,例如@ViewChild('.active')@ViewChild('[active]').
  • 好的,重要的是现在它可以工作了,而在你之前这完全是晦涩难懂的。千恩万谢! :)
  • 很高兴我能帮上忙。 :)
  • (我根据您的解决方案提出了一个问题,关于如何将变量传递给克隆的模板,仍在苦苦挣扎)stackoverflow.com/questions/42057886/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-10
  • 2012-10-17
相关资源
最近更新 更多