How to dynamically add a cloned node in angular2 (equivalent to cloneNode)

前端 未结 1 1888
生来不讨喜
生来不讨喜 2021-01-14 08:14

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 doe

相关标签:
1条回答
  • 2021-01-14 08:53

    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.

    0 讨论(0)
提交回复
热议问题