ngComponentOutlet dynamically renders a component selected through a component-class reference, placing it where the directive appears in the template. section 4.1.4
Use it for components that should be selected or loaded at runtime:
- Select a component class in TypeScript when template branching becomes too complicated for a simple *ngSwitch. section 4.1.4
- Load a standalone component on demand with a dynamic import, then pass the resolved class through the async pipe or a component property. section 2.4.5
- Pass parent data through the inputs record, such as inputs: {candidateId: candidate.id}; input names must currently be spelled correctly because the mechanism is not type-safe. section 4.1.4
Candidate actions and employee deletion
A candidate-details component selects an actions component from the candidate status and renders it with ngComponentOutlet, passing candidateId as an input. In an employee list, clicking Delete dynamically imports a confirmation dialog, stores its class reference, and renders it in an ng-container only when needed. section 4.1.4 section 2.4.5
Listing 2.18 EmployeeListComponent
@Component({
selector: 'app-employee-list',
template: `
<h2>Employee List</h2>
<table>
<thead>
<tr>
<th>Full Name</th>
<th>Position</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let employee of employees$ | async">
<td>{{ employee.firstName }} {{ employee.lastName }}</td>
<td>{{ employee.position }}</td>
<td>
<button (click)="showConfirmationDialog()">Delete</button>
</td>
</tr>
</tbody>
</table>
`,
standalone: true,
imports: [AsyncPipe, NgFor, NgIf, NgComponentOutlet],
})
export class EmployeeListComponent {
employees$ = this.employeeService.getEmployees();
isConfirmationOpen = false;
constructor(private readonly employeeService: EmployeeService) {}
showConfirmationDialog() {
this.isConfirmationOpen = true;
}
}
The EmployeeListComponent listing shows the standalone imports, employee table, delete action, and directive placement used for on-demand rendering. section 2.4.5
