angular templateRef nativeElement is an empty comment instead of original element
Asked Answered
E

2

8

I am developing an angular directive that converts dropdownlist to radioListbox. here is my initial code :

import { Directive, Input, TemplateRef, ViewContainerRef,OnInit } from '@angular/core';

@Directive({
  selector: '[radioList]'
})
export class RadioListDirective implements OnInit  {



  constructor(private templateRef: TemplateRef<any>, private vcRef: ViewContainerRef) {

  }

  ngOnInit() {

    console.log(this.templateRef);
    this.vcRef.createEmbeddedView(this.templateRef);

  }
}

and

<div>
  test
</div>


<select *radioList><option>1</option><option>2</option></select>

It should log the TemplateRef whose ElementRef 's nativeElement is a select. But the result is and empty comment that its next element is the select .

enter image description here

Enough answered 8/5, 2018 at 7:47 Comment(5)
Try private templateRef: TemplateRef<any>Stela
I tried before. Still wont work.Enough
It should log the TemplateRef whose ElementRef 's nativeElement is a select where did you read that? It works as intendedWherever
@Wherever where do you read that this is the intended behavior (referencing an empty comment )?Enough
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. https://mcmap.net/q/1470098/-elementref-is-undefined-in-templaterefWherever
H
6

Hacky solutions currently working:

Grab the next sibling:

this.templateRef.elementRef.nativeElement.nextSibling

Use viewContainerRef.get

(this.viewContainerRef.get(0) as any).rootNodes[0]

(Note, from your example code you used vcRef instead of viewContainerRef as I used here.)

Hecht answered 21/2, 2019 at 21:59 Comment(0)
E
0

Find answered in Empty native element with ng-template

The ElementRef 's nativeElement has nothing to do with the radioList, and it is to be a comment element:

<!---->

This is a preserved feature that, if you binding directive paramater as a input, such that

<select *radioList="true"><option>1</option><option>2</option></select>

Then the directive can have:

@Input('radioList') isEnabled: boolean;

And the rendered ElementRef 's nativeElement becomes:

<!--bindings={
  "ng-reflect-is-enabled": "true"
}-->

So in conclusion, it is expected.

To continue your code, the createEmbeddedView creates a container for everything to be implemented by the vcRef, so you can inject cfResolver: ComponentFactoryResolver to resolve e.g. another template component:

const cmpFactory = this.cfResolver.resolveComponentFactory(SomeOtherComponent);
this.vcRef.createComponent(cmpFactory);
Electrocautery answered 5/1, 2023 at 16:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.