I have a Angular Material Dialog Component that takes Inputs and uses them in header and footer of modal. I want to pass some html elements in modal's body section from another component.
I want to have a reference of child elements of a component in that component. I have tried both ElementRef, TemplateRef and QueryList with ViewChild, ViewChildren, ContentChild, ContentChildren but no luck.
dashboard.component.html displays a 'show/hide columns' button.
dashboard.component.html
<app-modal [title]="title" [btnText]="text'>
<section #template>
<mat-form-field appearance="outline" *ngIf="!showForm && viewParams.length > 0 && cn_hostname_index >= 0">
<mat-label>Search Columns</mat-label>
<input
matInput
id="columnSearchTxt"
placeholder="Search Columns"
name="columnSearchTxt"
[(ngModel)]="colSearch.title"
/>
<button *ngIf="colSearch.title" (click)="colSearch.title = ''" mat-icon-button matSuffix (click)="searchHosts()" matTooltip="Filter on hostname">
<mat-icon aria-hidden="false" aria-label="Clear">close</mat-icon>
</button>
</mat-form-field>
<mat-slide-toggle
*ngFor="let col of colDefs | filter: 'title':colSearch.title"
color="primary"
[name]="col.title"
[(ngModel)]="col.includeField"
labelPosition= "before"
>
{{ col.title }}
</mat-slide-toggle>
</section>
</app-modal>
I want a complete reference of section
element along with its children as html elements. So that I can send the same ref to another component and display as innerHTML in dev.
modal.component.ts
import { Component, Inject, Input, TemplateRef, ViewChild, ContentChild, ElementRef } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
export interface DialogData {
title: string;
text: string;
template: TemplateRef<any>
}
@Component({
selector: 'app-modal',
template: `<button mat-raised-button (click)="openDialog()">{{ btnText }}</button>`,
styleUrls: ['./modal.component.scss']
})
export class ModalComponent {
@Input() btnText: string;
@Input() id: string;
@Input() modalTitle: string;
@Input() okText: string;
@Input() name: string;
// @ContentChild('template') template: TemplateRef<any>;
// @ContentChild('template') template: ElementRef<any>;
// @ViewChild('template') template: TemplateRef<any>;
@ViewChild('template') template: ElementRef;
constructor(public dialog: MatDialog) { }
openDialog(): void {
const dialogRef = this.dialog.open(ModalDialogComponent, {
data: {
id: this.id,
title: this.modalTitle,
text: this.okText,
name: this.name,
template: this.template
},
});
}
}
@Component({
selector: 'modal-dialog',
templateUrl: './modal-dialog.component.html',
})
export class ModalDialogComponent {
constructor(
public dialogRef: MatDialogRef<ModalDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: DialogData,
) {}
onNoClick(): void {
this.dialogRef.close();
}
}
modal-dialog.component.html
<section>
<div>
<mat-icon (click)="onNoClick()" aria-hidden="false" aria-label="close icon">close</mat-icon>
</div>
<h1 mat-dialog-title>{{ data.title }}</h1>
<div mat-dialog-content>
<!-- Want to display html elements from app-modal -->
</div>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">{{ data.text ? data.text : 'Ok' }}</button>
</div>
</section>
Top comments (1)
Hi Ram,
You cannot query for a reference defined in other component template, since each template is a black box to its relatives.
You have to add the following in the ModalComponent template
<ng-template #template><ng-content></ng-content></ng-template>
to capture the projected content you have defined inside the<app-modal>
in the dashboard.modal.component.ts
Then you can pass the templateRef in the dialog data and print the
data.template
content in the modal-dialog component using a template-outlet like<ng-container *ngTemplateOutlet="data.template"></ng-container>
modal-dialog.component.html
Cheers