5

Để hiểu về ViewEncapsulation trong Angular, trước tiên, chúng ta nên hiểu  Shadow DOM. Bạn có thể tìm hiểu chi tiết về  Shadow DOM tại đây . Nói một cách đơn giản, Shadow DOM mang đến sự đóng gói  cho các phần tử HTML. Sử dụng Shadow DOM, đánh dấu, kiểu và hành vi được đặt trong phạm vi phần tử và không xung đột với các nút khác của DOM. Shadow DOM là một phần của Thành phần Web, gói gọn các kiểu và đăng nhập của phần tử.

Các thành phần góc được tạo thành từ ba điều:

  1. Lớp thành phần
  2. Bản mẫu
  3. Phong cách

Sự kết hợp của ba yếu tố này làm cho một thành phần Angular có thể tái sử dụng trên một ứng dụng. Về mặt lý thuyết, khi bạn tạo một thành phần, theo một cách nào đó, bạn tạo một thành phần web ( về mặt lý thuyết, Thành phần góc không phải là thành phần web ) để tận dụng Shadow DOM. Bạn cũng có thể sử dụng Angular với các trình duyệt không hỗ trợ Shadow DOM vì Angular có phần mô phỏng riêng và nó có thể mô phỏng  Shadow DOM.

Để mô phỏng Shadow DOM và các kiểu đóng gói, Angular cung cấp các kiểu Xem đóng gói. Chúng là như sau:

Hãy thử hiểu nó bằng một ví dụ. Tôi đã tạo ra một thành phần, như được hiển thị 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 tôi đang thiết lập kiểu  h1 trong CSS thành phần. Chúng tôi cũng đã tạo ra 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 tôi cũng đang sử dụng  h1 thẻ. Để hiểu các ViewEncapsulation tùy chọn khác nhau  , chúng tôi sẽ thay đổi siêu dữ liệu của  AppComponent.

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

  1. Không có bóng DOM.
  2. Phong cách không nằm trong phạm vi thành phần.

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

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
    encapsulation: ViewEncapsulation.None
})
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  h1 kiểu đã được khai báo trong phần đầu của DOM.

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

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

  1. Angular sẽ tạo Shadow DOM cho thành phần.
  2. Phong cách là phạm vi cho các thành phần.

Khi bạn chạy ứng dụng, bạn sẽ thấy  h1 kiểu đã áp dụng cho cả hai thành phần, mặc dù chúng tôi chỉ đặt kiểu chỉ trong  AppComponent. Điều này xảy ra bởi vì trong  AppComponent chúng tôi đã đặt thuộc tính đóng gói thành  ViewEncapsulation.Nativevà chúng tôi đang sử dụng  AppChildComponnet như một đứa trẻ bên trong mẫu 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ẽ tạo Shadow DOM cho  AppComponent và kiểu được đặt trong phạm vi đó.

Do đó, trong  ViewEncapsulation.Native, Angular tạo ra Shadow DOM và kiểu được đặt trong Shadow DOM đó.

Tiếp theo, hãy cùng chúng tôi khám phá ViewEncapsulation.Emulation, trong tùy chọn này:

  1. Angular sẽ không tạo Shadow DOM cho thành phần.
  2. Phong cách sẽ được phạm vi cho các thành phần.
  3. Đâ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';
}

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

Hãy cho chúng tôi xem làm thế nào Angular đạt được điều này. Trong 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 kiểu trong phần đầu của DOM và đưa ra một id tùy ý cho thành phần. Trên cơ sở ID, kiểu chọn được đặt trong phạm vi thành phần.

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

|
  • Nói thật, nội dung này dịch từ nguồn nào đấy bằng tool hoặc là người không có chuyên môn dịch ra, chứ làm gì phải dịch ra tất tần tật các danh từ kỹ thuật như thế?
    Đọc nội dung rất chi là kỳ cục luôn.
    VD: "...bạn sẽ thấy rằng các h1 phong cách từ..."
    "h1 phong cách" có ý nghĩa gì đâu? Đọc muốn méo cả miệng, chẹo cả lưỡi @@ – LE KHAI HOAN 16:24:26 08/12/2019