简体   繁体   中英

How do I access DOM elements of an embedded template? (Angular 11)

Context

I have two Angular Components, a parent and a child. The parent passes an optional <ng-template> TemplateRef to the child as an @Input . The child then either renders this template or renders its default template if no input was given.

parent.component.html

// Pass in template as @Input 
<child [customTemplate]="parentTemplate"></child> 

// Define Custome Template 
<ng-template #parentTemplate>
   <div #container class="container">HELLO FROM CUSTOM CONTAINER</div>
</ng-template>

child.component.html

// Render correct template
<ng-container *ngTemplateOutlet="customTemplate || defaultTemplate;"> 
</ng-container>

// Define default template 
<ng-template #defaultTemplate>
  <div #container class="container">HELLO FROM DEFAULT CONTAINER</div>
</ng-template>

child.component.ts

export class ChildComponent implements AfterViewInit {
  @Input() public customTemplate!: TemplateRef<HTMLElement>
  @ViewChild("container")
  containerRef!: ElementRef;

  ngAfterViewInit() {
   console.log(this.containerRef?.nativeElement.offsetWidth)
  }
}

The Issue

I'd like to be able to access DOM Elements rendered by my child component. For example, say I want to find the width of an HTML Element currently rendered on screen.

If I define a template variable #container in both the customTemplate & the defaultTemplate, and then try to access that element using @ViewChild('container) or ContentChild('container) , it returns undefined on the customTemplate but returns the correct Element Reference with the default.

How do I access these embedded DOM elements, regardless of whether or not the template is passed in as an @Input or if we use the default?

Check out the Stackblitz below for an example of what I'm trying to accomplish. Hopefully it'll be self-explanatory.

Stackblitz Example with full project

I modified the code and I am using only a child component instead of two like your example, in my solution I used ternary operator to decide which template I need to render.

My solution on stackblitz

app.componen.ts

<!-- Call to Child Component -->
<div class="childComponent">
  <child [customTemplate]="displayCustom ? parentTemplate : null"></child>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM