ViewEncapsulation trong Angular

916
12-09-2024
ViewEncapsulation trong Angular

Để hiểu về ViewEncapsulation trong Angular, việc nắm bắt Shadow DOM là điều tiên quyết. Bài viết này Bizfly Cloud sẽ giúp bạn khám phá ba kiểu View Encapsulation mà Angular cung cấp, giúp định hình phong cách và hành vi của các thành phần trong ứng dụng.

Khái niệm cơ bản về Shadow DOM và ViewEncapsulation

Để hiểu về ViewEncapsulation trong Angular, trước hết chúng ta cần hiểu về Shadow DOM. Đơn giản, Shadow DOM mang đến tính năng đóng gói cho các phần tử HTML. Sử dụng Shadow DOM, đánh dấu, phong cách và hành vi sẽ được giới hạn trong phạm vi của phần tử và không gây xung đột với các nút khác trên DOM. Shadow DOM là một phần của Web Components, giúp đóng gói phong cách và logic của phần tử.

Khái niệm cơ bản về Shadow DOM và ViewEncapsulation

Khái niệm cơ bản về Shadow DOM và ViewEncapsulation

Các thành phần Angular được tạo nên từ ba yếu tố:

  • Lớp Component
  • Template
  • Style

Sự kết hợp này làm cho thành phần Angular có thể tái sử dụng trong toàn bộ ứng dụng. Lý thuyết cho rằng, khi bạn tạo một thành phần, bạn đang tạo một web component để tận dụng Shadow DOM. Bạn cũng có thể sử dụng Angular với trình duyệt không hỗ trợ Shadow DOM bởi Angular có khả năng mô phỏng và có thể mô phỏng Shadow DOM.

Ba loại View Encapsulation trong Angular

Angular cung cấp ba loại View Encapsulation để mô phỏng Shadow DOM và đóng gói phong cách. Chúng bao gồm:

Hãy cùng tìm hiểu thông qua một ví dụ. Tôi đã tạo một thành phần như dưới đây:

app.component.ts

import Component, ViewEncapsulation from '@angular/core'; @Component( selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], encapsulation: ViewEncapsulation.None ) export class AppComponent title = 'parent component';

app.component.html app.component.css

h1 background: red; color: white; text-transform: uppercase; text-align: center;

Chúng ta đã thiết lập phong cách cho thẻ h1 trong CSS của thành phần. Chúng ta cũng đã tạo một thành phần khác:

import Component from '@angular/core'; @Component( selector: 'app-child', template: ` <h1> title </h1> ` ) export class AppChildComponent title = 'child app';

Trong AppChildComponent, chúng ta cũng sử dụng thẻ h1. Để hiểu các tùy chọn ViewEncapsulation khác nhau, chúng ta sẽ thay đổi metadata của AppComponent.

Tùy chọn ViewEncapsulation.None

Hãy bắt đầu với ViewEncapsulation.None, trong tùy chọn này:

  • Không có shadow DOM.
  • Phong cách không được giới hạn trong thành phần.

Khi bạn chạy ứng dụng, bạn sẽ thấy phong cách của h1 đã được áp dụng cho cả hai thành phần, mặc dù chúng ta chỉ thiết lập phong cách trong AppComponent. Điều này xảy ra bởi vì trong AppComponent chúng ta đã thiết lập thuộc tính đóng gói là ViewEncapsulation.None.

@Component( selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], encapsulation: ViewEncapsulation.None ) export class AppComponent title = 'parent component';

Trên trình duyệt, khi bạn kiểm tra mã nguồn, bạn sẽ thấy phong cách của h1 đã được khai báo trong phần đầu của DOM.

Do đó, trong ViewEncapsulation.None, phong cách được chuyển đến phần đầu của DOM và không được giới hạn trong thành phần. Không có Shadow DOM cho thành phần và phong cách của thành phần có thể ảnh hưởng đến tất cả các nút trong DOM.

Tùy chọn ViewEncapsulation.Native

Tiếp theo, hãy khám phá ViewEncapsulation.Native, trong tùy chọn này:

  • Angular sẽ tạo Shadow DOM cho thành phần.
  • Phong cách được giới hạn trong thành phần.

Khi bạn chạy ứng dụng, bạn sẽ thấy phong cách h1 được áp dụng cho cả hai thành phần, mặc dù chúng ta chỉ thiết lập phong cách trong AppComponent. Điều này xảy ra bởi vì trong AppComponent chúng ta đã thiết lập thuộc tính đóng gói là ViewEncapsulation.Native, và chúng ta đang sử dụng AppChildComponent như một thành phần con bên trong template của AppComponent.

import Component, ViewEncapsulation from '@angular/core'; @Component( selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], encapsulation: ViewEncapsulation.Native ) export class AppComponent title = 'parent component';

Trong trình duyệt, khi bạn kiểm tra mã nguồn, bạn sẽ thấy đã tạo một Shadow DOM cho AppComponent và phong cách được giới hạn cho nó.

Vì vậy, trong ViewEncapsulation.Native, Angular tạo ra một Shadow DOM và phong cách được giới hạn trong Shadow DOM đó.

Tùy chọn ViewEncapsulation.Emulated

Cuối cùng, hãy tìm hiểu về ViewEncapsulation.Emulated, trong tùy chọn này:

  • Angular không tạo Shadow DOM cho thành phần.
  • Phong cách sẽ được giới hạn trong thành phần.
  • Đây là giá trị mặc định cho đóng gói.

import Component, ViewEncapsulation from '@angular/core'; @Component( selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], encapsulation: ViewEncapsulation.Emulated ) export class AppComponent title = 'parent component';

Khi bạn chạy ứng dụng, bạn sẽ thấy rằng phong cách h1 từ AppComponent không được áp dụng cho h1 của AppChildComponent. Điều này là do việc mô phỏng giới hạn phong cách. Trong tùy chọn này, phong cách chỉ được giới hạn cho thành phần. Angular chỉ mô phỏng Shadow DOM mà không tạo ra một Shadow DOM thực sự. Do đó, ứng dụng chạy trên trình duyệt không hỗ trợ Shadow DOM cũng có phong cách được giới hạn cho thành phần tương tự.

Hãy xem Angular thực hiện điều này như thế nào. Trên trình duyệt, khi bạn kiểm tra mã nguồn, bạn sẽ tìm thấy câu trả lời.

Angular đã tạo phong cách trong phần đầu của DOM và cấp một ID tuỳ ý cho thành phần. Dựa vào ID, phong cách của bộ chọn được giới hạn cho thành phần.

Đây là ba tùy chọn ViewEncapsulation có sẵn trong Angular. Tôi hy vọng bạn thấy bài viết này hữu ích. Cảm ơn bạn đã đọc. Nếu bạn thích bài viết này, hãy chia sẻ nó.

SHARE