如何在angular2中动态添加克隆节点(相当于cloneNode) [英] How to dynamically add a cloned node in angular2 (equivalent to cloneNode)

查看:2620
本文介绍了如何在angular2中动态添加克隆节点(相当于cloneNode)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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:克隆组件/ HTML元素及其功能

  @Component({
selector:'my-app',
template:`
< template#temp>
< h1 [ ngStyle] ={background:'green'}>测试< / 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;
}

但是如何动态添加模板?

解决方案

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

 < p>段落1< / p> 
< p>段落2< / p> <! - 让我们尝试克隆这个人 - >
< p>段落3< / p>

选项1 - 手动包装元素以克隆 ; template> 标签



这基本上是你所做的,只是用 ngTemplateOutlet ,在组件的类中引用它,并用 createEmbeddedView()插入它。

  @Component({
selector:'my-app',
template:`
< ; p> Paragraph One< / p>
< template#clone>
< p>段落2< / p>
< / template>
< p>第三段< / p>

< button(click)=cloneTemplate()>克隆模板< / button>

< div#container> / div>
`
})
导出类AppComponent {
//要克隆的内容
@ViewChild('clone')模板;

//插入克隆内容的位置
@ViewChild('container',{read:ViewContainerRef})容器;

构造函数(私有解析器:ComponentFactoryResolver){}

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

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



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

选项2 - 使用结构指令



如果要克隆元素在其当前位置,结尾为:

 < p>第一段< / p> 
< p>段落2< / p> <! - 原始段落>>
< p>段落2< / p> <! - 克隆段落>
< p>段落3< / p>

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

 < p>段落1< / p> 
< p * clone>段落2< / p>
< p>段落3< / p>

有趣的是,结构指令的作用是将其应用的元素包含在$ code>< template> 标签。非常类似于我们在选项1中所做的,只有在这种情况下,我们在克隆被打印出的位置没有控制(它们将出现在原始段落的位置)。



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


In Angular2, I need to duplicate a node rather than moving it in some cases. That node has angular2 properties so cloneNode doesn't work. How can I do it?

*what doesn't work

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

*what would work, from 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;
} 

But how to add a template dynamically?

解决方案

Let's use the following markup for illustration:

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

Option 1 - Manually wrap the element to clone inside a <template> tag

This is basically what you did, only instead of printing out the template with ngTemplateOutlet, grab a reference to it in your component's class and insert it imperatively with 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);
    }
}

In this example, I'm inserting the "clone" at a specific location in the markup (<div #container></div>), but you could also append it at the bottom of the current component's template.

Also note that the original <p>Paragraph Two</p> is no longer visible.

Option 2 - Use a structural directive

If you want to clone an element at its current location, ending up with:

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

Then you could create a structural directive *clone and apply it to the paragraph to clone, like this:

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

Interestingly, what a structural directive does is wrap the element it is applied to inside a <template> tag. Pretty similar to what we did in option 1, only in that case we have NO CONTROL over the location where the clones are printed out (they will appear where the original paragraph was).

This would essentially replicate *ngFor's behavior so it's probably not very useful. Also, it seems from your comment to yurzui that it's not what you want.

这篇关于如何在angular2中动态添加克隆节点(相当于cloneNode)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆