Những directive tùy biến của Angular cung cấp một cơ chế mạnh mẽ cho việc chỉnh sửa DOM và kết hợp hành vi năng động cho các template.
Một trong số những tính năng chính của Angular là directive. Các directive của Angular cho bạn cách thêm hành vi vào những thành phần DOM. Angular cung cấp sẵn một loạt các directive. Bạn cũng có thể tạo directive tùy chỉnh trong framework mạnh mẽ này.
Directive là gì?
Directive là code tùy chỉnh mà Angular sử dụng để chỉnh sửa hành vi hoặc hình ảnh của thành phần HTML. Bạn có thể dùng directive để thêm trình nghe sự kiện, thay đổi DOM, hiện hoặc ẩn các thành phần.
Angular có hai kiểu directive: structural và attribute. Structural directive thay đổi cấu trúc của DOM, còn attribute directive thay đổi hình ảnh hoặc hành vi của một thành phần. Directive là cách mở rộng hiệu quả các thành phần của Angular.
Lợi ích khi sử dụng Directive trong Angular
- Có thể tái sử dụng trong nhiều thành phần, giúp bạn tiết kiệm thời gian và công sức.
- Có thể mở rộng directive để thêm chức năng mới, khiến các thành phần trở nên mạnh mẽ hơn.
- Linh hoạt trong chỉnh sửa hành vi hay hình ảnh của một thành phần theo nhiều cách khác nhau, cho bạn rất nhiều tính linh hoạt khi xây dựng app.
Thiết lập ứng dụng Angular
Cài đặt Angular CLI bằng cách chạy code trong terminal:
npm install -g @angular/cli
Sau khi cài đặt Angular CLI, tạo một dự án Angular bằng cách chạy lệnh sau:
ng new custom-directives-app
Chạy lệnh trên sẽ tạo một dự án Angular tên custom-directives-app.
Tạo một chỉ lệnh tùy biến
Giờ bạn đã có một dự án Angular và có thể bắt đầu tạo các directive tùy biến. Tạo file TypeScript và xác định một class có chứa thành phần decorator @Directive.
@Directive là một decorator TypeScript được dùng để tạo các directive tùy chỉnh. Giờ tạo một file highlight.directive.ts trong danh mục src/app. Ở file này, bạn sẽ tạo directive tùy biến: highlight .
Ví dụ:
import { Directive } from "@angular/core";
@Directive({
selector: "[myHighlight]",
})
export class HighlightDirective {
constructor() {}
}
Khối code trên nhập decorator Directive từ mô đun @angular/core. Decorator @Directive sửa đổi class HighlightDirective. Nó lấy một đối tượng làm đối số bằng một thuộc tính selector.
Trong trường hợp này, bạn đặt thuộc tính selector sang [myHighlight], điều đó có nghĩa bạn có thể thể áp dụng directive này cho các mẫu bằng cách thêm thuộc tính myHighlight cho một thành phần.
Đây là ví dụ cách dùng directive trong template:
<main>
<p myHighlight>Some text</p>
</main>
Thêm hành vi cho Directive
Giờ bạn đã thành công tạo một directive. Bước tiếp theo là thêm hành vi vào directive để nó có thể thao tác với DOM. Bạn sẽ cần ElementRef từ @angular/core để thêm hành vi vào một directive.
Bạn sẽ đưa ElementRef vào hàm tạo của directive. ElementRef là một wrapper xoay quanh thành phần gốc bên trong một trình xem.
Sau đây là ví dụ về cách thêm hành vi vào một directive:
import { Directive, ElementRef } from "@angular/core";
@Directive({
selector: "[myHighlight]"
})
export class HighlightDirective {
constructor(private element: ElementRef) {
this.element.nativeElement.style.backgroundColor = 'lightblue';
}
}
Ở ví dụ này, hàm tạo class HighlightDirective lấy tham số ElementRef, mà Angular tự động đưa vào. ElementRef cấp quyền truy cập tới thành phần DOM cơ bản.
Dùng thuộc tính this.element.nativeElement, bạn có quyền truy cập thành phần DOM gốc của tham số element. Sau đó, bạn đặt màu nền của thành phần vào lightblue bằng thuộc tính style. Điều này có nghĩa bất kỳ thành phần nào bạn áp dụng cho directive myHighlight đều sẽ có nền xanh nhạt.
Để làm directive hoạt động được, đảm bảo bạn nhập và khai báo nó trong file app.module.ts.
Ví dụ:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HighlightDirective } from './highlight.directive';
@NgModule({
declarations: [
AppComponent,
HighlightDirective,
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Giờ bạn có thể áp dụng directive myHighlight cho các nhân tố trong thành phần Angular.
<main>
<p myHighlight>Some text</p>
</main>
Chạy ứng dụng trên server thành phần để kiểm tra xem directive đó có hoạt động hay không. Bạn có thể làm việc này bằng cách chạy lệnh sau trong terminal:
ng serve
Sau khi chạy lệnh này, điều hướng tới http://localhost:4200/ trên trình duyệt web, và bạn sẽ thấy một giao diện trông như ảnh bên dưới.
Các directive sẵn có trong Angular chấp nhận những giá trị thay đổi hình ảnh phần tử, nhưng directive tùy biến myHighlight thì không. Bạn có thể cấu hình directive để chấp nhận một giá trị nó sẽ dùng để đặt linh động màu nền của template.
Để làm việc này, thay code trong file highlight.directive.ts bằng:
import { Directive, ElementRef, Input } from "@angular/core";
@Directive({
selector: "[myHighlight]"
})
export class HighlightDirective {
@Input() set myHighlight(color: string) {
this.element.nativeElement.style.backgroundColor = color;
}
constructor(private element: ElementRef) {
}
}
Ở khối code trên, class HighlightDirective chứa một phương thức setter tên myHightlight. Nó lấy tham số color của chuỗi type. Bạn sửa setter bằng decorator@Input, cho phép bạn chuyển giá trị màu vào directive từ thành phần gốc.
Giờ bạn có thể quyết định màu nền bằng cách chuyển giá trị sang directive myHighlight.
Ví dụ:
<main>
<p myHighlight='pink'>Some text</p>
</main>
Tạo directive cấu trúc tùy chỉnh
Angular cung cấp hai structural directive: ngFor và ngIf. Directive ngFor hiện một template cho từng mục trong bộ sưu tập (mảng), còn nglf xử lý hiển thị theo điều kiện.
Ở phần này, bạn sẽ tạo một directive cấu trúc tùy biến có chức năng giống như directive nglf. Để làm việc này, tạo file condition.directive.ts.
Trong file condition.directive.ts, viết code sau:
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'
@Directive({
selector: "[condition]"
})
export class ConditionDirective {
@Input() set condition(arg: boolean) {
if(arg) {
this.viewContainer.createEmbeddedView(this.template)
} else {
this.viewContainer.clear();
}
}
constructor(
private template: TemplateRef<unknown>,
private viewContainer: ViewContainerRef
) {}
}
Khối code này cho phép bạn hiện các thành phần theo điều kiện bằng cách áp dụng directive condition cho một thành phần và chuyển giá trị boolean từ thành phần gốc.
Trong hàm tạo class ConditionDirective, bạn chèn một phiên bản của TemplateRef và ViewContainerRef. TemplateRef đại diện cho template được liên kết với directive đó, còn ViewContainerRef đại diện cho container mà ứng dụng hiện các cửa sổ xem.
Phương thức setter class ConditionDirective dùng lệnh if else để kiểm tra tham số arg. Directive tạo một cửa sổ nhúng bằng mẫu được cung cấp nếu tham số đó là đúng. Phương thức createEmbeddedView của class ViewContainerRef tạo và hiện trình xem trong DOM.
Nếu tham số đó là false, directive này sẽ xóa container trình xem bằng phương thức clear của class ViewContainerRef. Điều này loại bỏ bất kỳ các trình xem được hiện trước đó từ DOM.
Sau khi tạo directive, đăng ký nó trong dự án bằng cách nhập và khai báo nó ở file app.module.ts. Sau khi làm việc này, bạn có thể bắt đầu dùng directive trong các template của bạn.
Đây là ví dụ về cách dùng nó trong template của bạn:
<main>
<p *condition="true">Hello There!!!</p>
</main>
Giờ bạn có thể thoải mái tạo các directive tùy biến rồi đấy. Đừng ngại dùng chức năng này vì nó có thể giúp bạn chỉnh sửa DOM và làm template trở nên thú vị hơn.