Structural directive (những cái có *, như *ngIf/*ngFor) thay đổi DOM bằng cách . Dấu là cú pháp viết tắt — bên dưới, Angular bọc phần tử trong một và directive kiểm soát việc/cách template đó được render.
Structural directive (những cái có *, như *ngIf/*ngFor) thay đổi DOM bằng cách . Dấu là cú pháp viết tắt — bên dưới, Angular bọc phần tử trong một và directive kiểm soát việc/cách template đó được render.
*<ng-template><!-- những gì bạn viết -->
<p *ngIf="isVisible">Hello</p>
<!-- những gì Angular thực sự làm -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
Dấu * báo cho Angular: "bọc phần tử này trong một template, và để directive quyết định khi nào đóng dấu nó vào DOM." Một <ng-template> là một đoạn markup trơ, không được render cho tới khi một directive khởi tạo nó.
import { Directive, Input, TemplateRef, ViewContainerRef } from "@angular/core";
@Directive({ selector: "[appUnless]" }) // *appUnless = "ngược lại với ngIf"
export class UnlessDirective {
constructor(
private templateRef: TemplateRef<any>, // <ng-template> được bọc
private viewContainer: ViewContainerRef, // nơi để render nó
) {}
@Input() set appUnless(condition: boolean) {
if (!condition) {
this.viewContainer.createEmbeddedView(this.templateRef); // render nó
} else {
this.viewContainer.clear(); // xóa nó
}
}
}
// cách dùng: <p *appUnless="isHidden">Hiện khi isHidden là false</p>
Hai mảnh được inject vào là then chốt: TemplateRef là template của phần tử ("render cái gì"), và ViewContainerRef là vị trí trong DOM ("render ở đâu"). Directive gọi createEmbeddedView để thêm phần tử hoặc clear để xóa nó.
<!-- Angular mới hơn thay thế *ngIf/*ngFor bằng cú pháp block tích hợp sẵn -->
@if (isVisible) { <p>Hello</p> } @else { <p>Hidden</p> }
@for (item of items; track item.id) { <li>{{ item.name }}</li> }
Cú pháp mới hơn này dễ đọc và hiệu năng hơn, dù khái niệm thêm/xóa bên dưới vẫn như nhau.
Hiểu việc khai triển * → <ng-template> làm sáng tỏ cách *ngIf/*ngFor thêm và xóa DOM, và cho phép bạn xây dựng structural directive tùy chỉnh (dùng TemplateRef + ViewContainerRef) cho các kiểm soát template nâng cao — ví dụ render dựa trên quyền, repeater tùy chỉnh, hoặc đóng dấu lười.
Nó cũng làm rõ vì sao bạn không thể đặt hai structural directive (*ngIf và *ngFor) trên một phần tử: mỗi cái cần lớp bọc template riêng của nó.
Thư viện câu hỏi phỏng vấn IT với đáp án chi tiết — từ Junior đến Senior.
Ủng hộ