1

In Angular2 I have a template code that I am cloning whenever the user clicks a button, just like answered here How to dynamically add a cloned node in angular2 (equivalent to cloneNode)

I am trying to pass a variable to it, but it doesn't work. What's wrong?

import {Component, NgModule, ViewChild, ViewContainerRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <template #clone let-session>
     <div [id]="session">eps {{session}} ya</div>
    </template>

    <div #container></div>

    <div>
      <button (click)="create()">Hello</button>
    </div>
  `,
})
export class App {
  name:string;

    @ViewChild('clone') clone:any;
    @ViewChild('container', {read:ViewContainerRef}) container:any;

  constructor() {
    this.name = 'Angular2'
  }

  create(){
    let session = 'testing';
        this.container.createEmbeddedView(this.clone, {context: {$implicit: session}});
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

And the plunker https://plnkr.co/edit/pWeQfTLroOjKoyKnaZvL?p=preview

Community
  • 1
  • 1
GWorking
  • 4,011
  • 10
  • 49
  • 90
  • Why don't you just pass the `id` to an input of the directive? – Günter Zöchbauer Feb 06 '17 at 06:15
  • I will read about it, right now I wouldn't know how to do it – GWorking Feb 06 '17 at 09:17
  • It would be helpful to see more code. What is the directive? Actually you could even pass the element itself, so you don't have to query for it. – Günter Zöchbauer Feb 06 '17 at 09:25
  • I've added the code for the directive (if it helps). – GWorking Feb 06 '17 at 09:37
  • Where do you do the cloning? Why don't you just keep a reference? What value do you want to dynamically change? – Günter Zöchbauer Feb 06 '17 at 09:40
  • I do the cloning in the component that has the template (external template). When the user clicks the button (as many times as he wishes) then I clone the template. So what I don't know is how many clones the user will want, that's why I need it to be dynamic. Right now the cloning works, but the drag-and-drop does not because the directive of the template does not contain the information of the clone when I (dynamically) change it – GWorking Feb 06 '17 at 09:43
  • So when I clone the template I need to change its ID for a unique one, and then I need to add this ID to the custom directive as well. I suspect that I could put a variable in the custom directive and that I could access it and change it, but I don't know how to do it – GWorking Feb 06 '17 at 09:45

2 Answers2

5

I've updated your plunkr, basically answer could be found in #8368:

<template #clone let-context="context">
 <div [id]="context.session">eps {{context.session}} ya</div>
</template>

this.container.createEmbeddedView(this.clone, {context: {session: session}});
kemsky
  • 14,727
  • 3
  • 32
  • 51
  • Thanks! And could you please expand in why your answer does work and why Günter's one does not? Or more importantly, is there any documentation I've skipped that described this? (I'm afraid your link is obscure to me) – GWorking Feb 18 '17 at 06:45
  • It looks like documentation for method `createEmbeddedView` is quite limited. Context parameter contains all properties available in template, your example can be simplified to `{session:session}` and `let-session="session"`. – kemsky Feb 18 '17 at 19:10
1
create_new_session(s : string) {
    this.container.createEmbeddedView(this.clone, {context: {$implicit: session}});
}
<template #clone let-session>
<section [id]="session"
    [bookmark_draggable_target]="{event_type:'moving_sessions',zone:'title_template'}"
    (drop_here)="onDrop($event)">
</section>
</template>

https://angular.io/docs/ts/latest/api/core/index/ViewContainerRef-class.html#!#createEmbeddedView-anchor

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567