Manu Chadha
Manu Chadha

Reputation: 16723

ElementRef is undefined in TemplateRef

Experimenting with ElementRef, TemplateRef, ViewRef and ViewContainerRef in Angular. I have created an HTML template, from there I want to create a View and pass that view to ViewContainerRef but it isn't working

Code for template

template: `
  <ng-container #vc></ng-container>
  <ng-template #mytmpl>
    <div>Name: <input type="text" name="name" /> </div>
    <div>Gender: 
      <select  name="gender" >
        <option>Male(1)</option>
        <option>Female(2)</option>
      </select>
    </div>
    <div>About you: <textarea ></textarea></div>
    <div>Married: <input type="checkbox" /></div>      
    <div>Children:     
      <ng-container *ngFor = "let option of this.selectOptions">
        <input  type="radio" [id]="option" name="children" [value]=option [(ngModel)]="this.children"/> {{option}}
      </ng-container>
   </div>
   <p>Some para</p>
   <p>Para with span <span>Inside span</span></p>
  </ng-template>
`

In the class, I access the template and view container

@ViewChild('vc',{read:ViewContainerRef}) v:ViewContainerRef;
@ViewChildren("mytmpl") myTemplateList:TemplateRef<any>;

I use the following code to create the view

ngAfterViewInit(){
  let elementRef = this.myTemplateList.elementRef
  let view = this.myTemplateList.createEmbeddedView(null)
  this.v.insert(view)
  console.log(elementRef);
}

Problems

1) elementRef is undefined!- I want to print on the console, all the elements inside the template. but elementRef is undefined!

2) I get the error that createEmbeddedView is not a function.

Upvotes: 5

Views: 11835

Answers (1)

Max Koretskyi
Max Koretskyi

Reputation: 105499

I get the error that createEmbeddedView is not a function.

There are few problems:

1) Use {read: TemplateRef} here:

@ViewChildren("mytmpl", {read: TemplateRef}) myTemplateList:TemplateRef<any>;

2) If you use ViewChildren, not ViewChild, it returns a collection so you need to access the member by the index:

myTemplateList.first

So it becomes:

@ViewChildren("mytmpl", {read: TemplateRef}) myTemplateList:TemplateRef<any>;
...
let view = this.myTemplateList.first.createEmbeddedView(null)

Or simply use ViewChild:

@ViewChild("mytmpl", {read: TemplateRef}) myTemplateList:TemplateRef<any>;
...
let view = this.myTemplateList.createEmbeddedView(null)

1) elementRef is undefined!- I want to print on the console, all the elements inside the template. but elementRef is undefined!

You can't directly access the elements from the templateRef. You need to follow the same process using @ViewChildren. The elementRef that is available on the templateRef as shown here just points to the DOM host element that Angular created for the template element - it's a comment node. It's not what you think it is, not the contents of the template. To get it just use:

this.myTemplateList.first.elementRef

Read Exploring Angular DOM manipulation techniques using ViewContainerRef for more details.

Upvotes: 3

Related Questions