Để đơn giản, chúng tôi sẽ sử dụng một thành phần
9 đơn giản sẽ lấy loại cảnh báo là
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
0
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Tiếp theo, nếu bạn nghĩ về nó, cuối cùng các thành phần là các phần tử DOM nên khi bạn cần thêm một phần tử, bạn cần một nơi để “đặt” nó
Trong Angular, nơi này được gọi là container
Trong thành phần
1, chúng tôi đang tạo một thành phần mẫu. Chúng tôi cũng đang sử dụng ký hiệu băm [#] để khai báo một biến tham chiếu có tên là
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
2. Phần tử
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
3 là địa điểm, hay trong thế giới Góc cạnh, nơi chứa
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Ghi chú. Vùng chứa có thể là bất kỳ phần tử hoặc thành phần DOM nào
Bây giờ chúng ta cần lấy một tham chiếu đến phần tử
3 của chúng ta trong thành phần
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
1
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Chúng ta có thể tham chiếu đến phần tử
3 với trình trang trí
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
7 cũng lấy một biến cục bộ làm tham số
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Trả về mặc định từ trình trang trí
7 là thể hiện thành phần hoặc phần tử DOM, nhưng trong trường hợp của chúng tôi, chúng tôi cần lấy phần tử là
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
00
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Như tên gợi ý,
01 là tham chiếu đến vùng chứa.
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
00 lưu trữ một tham chiếu đến phần tử
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
3 [ vùng chứa của chúng tôi ] và cũng hiển thị một API để tạo các thành phần
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Bạn có thể thấy nativeElement
Hãy thêm hai nút sẽ giúp chúng ta tạo thành phần
9
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Trước khi chúng tôi tiến hành phương pháp
05, chúng tôi cần thêm một dịch vụ nữa
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Dịch vụ
06 hiển thị một phương thức chính,
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
07
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Phương thức
08 lấy một thành phần và trả về một
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
09
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Bạn có thể nghĩ về
09 như một đối tượng biết cách tạo một thành phần
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Như bạn có thể thấy,
09 hiển thị phương thức
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
12 sẽ được sử dụng bởi vùng chứa [ ViewContainerRef ] trong nội bộ
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Bây giờ cho bước cuối cùng
Hãy giải thích những gì đang xảy ra từng mảnh
Mỗi khi chúng ta cần tạo thành phần, chúng ta cần xóa chế độ xem trước đó, nếu không, nó sẽ nối thêm nhiều thành phần vào vùng chứa. [không bắt buộc nếu bạn cần nhiều thành phần]
Phương thức
08 lấy một thành phần và trả về công thức về cách tạo một thành phần
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Chúng tôi đang gọi phương thức
05 với công thức. Trong nội bộ, phương thức này sẽ gọi phương thức
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
12 từ nhà máy và sẽ nối thành phần này với tư cách là anh chị em vào vùng chứa của chúng ta
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Thông thường, chúng ta cần hiển thị chế độ xem con một cách linh hoạt. Chẳng hạn, chúng tôi có thể có chế độ xem chính có menu tab và chúng tôi muốn hiển thị chế độ xem theo bất kỳ tab nào đang được chọn
Là người mới sử dụng Angular, đây là điều tôi trải nghiệm và tôi đã mất một khoảng thời gian kha khá để triển khai hoạt động mặc dù đã làm theo hướng dẫn chính thức của Angular. Đọc bài viết của Maxim Koretskyi về thao tác DOM chắc chắn đã giúp tôi hiểu rõ hơn, vì vậy tôi cũng khuyên bạn nên đọc nó, nếu bạn muốn giải thích sâu hơn
Trong phần này, tôi sẽ nêu bật và tóm tắt ba khái niệm chính sẽ nhanh chóng giúp bạn chạy
1. Tạo Chế độ xem
Trước khi chúng ta có thể chèn một dạng xem, trước tiên chúng ta phải biết cách tạo một dạng xem. Góc hỗ trợ hai loại chế độ xem, đó là chế độ xem máy chủ và chế độ xem được nhúng
Chế độ xem máy chủ
Đây là dạng xem chúng tôi sử dụng thường xuyên nhất và có lẽ quen thuộc nhất với. Khi Angular tạo một thành phần, chúng ta sẽ có một chế độ xem cũng chứa dữ liệu của thành phần đó. Khi chúng ta nói về chế độ xem máy chủ, về cơ bản chúng là chế độ xem thành phần được khởi tạo
Để tạo một thành phần, chúng tôi chỉ cần đưa bộ chọn của nó vào mẫu của một thành phần khác và Angular sẽ tự động thực hiện phần còn lại. Tuy nhiên, khi chúng tôi đang tạo động các chế độ xem, cần có hai bước trung gian
Chúng tôi cần một
5, sẽ được sử dụng theo cách thủ công [tôi. e. động] tạo một thành phần. Để có được
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
5, chúng ta cần sử dụng
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
0 bằng cách chuyển vào thành phần dưới dạng tham số
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Giả sử chúng ta muốn tạo một thành phần động khi khởi tạo
import { ..., ComponentFactoryResolver } from '@angular/core';
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
Quan trọng. Bạn cần xác định thành phần trong
2 của
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
1 trong tệp
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
3. Trong phần tải thành phần động của tài liệu Angular, phần này không được bao gồm và tôi phải mất một lúc để tìm ra nó
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
“Thành phần đầu vào là bất kỳ thành phần nào mà Angular bắt buộc phải tải [có nghĩa là bạn không tham chiếu nó trong mẫu] theo loại. ” - Góc cạnh. io
Chế độ xem được nhúng
This is rendered
This is not rendered
A
4 là một kế hoạch chi tiết để tạo các phần tử DOM, giống như cách một lớp đối với một thể hiện của chính nó. Khi bạn tham khảo một
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
5, bạn sẽ nhận được một
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
4. Nếu bạn bao gồm một
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
5 trong tệp
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
8 của mình, nó sẽ không được hiển thị vì bạn cần khởi tạo chế độ xem và nhúng nó sau. Trong phần sau, chúng ta sẽ nói về cách tham chiếu một phần tử DOM
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Hiện tại, chúng tôi chỉ cần biết rằng chúng tôi có thể chọn
5 thông qua tên bộ chọn của nó,
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
0 và rằng chúng tôi có thể tạo một phiên bản của nó — đó là cái mà chúng tôi gọi là chế độ xem được nhúngThis is rendered
This is not rendered
Nếu bạn quan tâm, bạn có thể đọc thêm về sự khác biệt giữa chế độ xem máy chủ và chế độ nhúng
2. Chọn phần tử DOM
Nếu bạn muốn hiển thị động một chế độ xem, bạn có thể tưởng tượng có một phần tử đóng vai trò là điểm neo để cho Angular biết vị trí nên chèn chế độ xem. Nếu bạn đã có kinh nghiệm với jQuery, nó sẽ tương tự như
import { ..., ComponentFactoryResolver } from '@angular/core';4
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
Trong Angular, chúng tôi sử dụng các bộ trang trí
1 vàThis is rendered
This is not rendered
2 để tìm kiếm [các] phần tử. Cả hai đều cung cấp chức năng tương tự, nhưng cái trước chỉ trả về một tham chiếu duy nhất. Cái sau trả về một đối tượngThis is rendered
This is not rendered
3 có nhiều tham chiếu đến các phần tửThis is rendered
This is not rendered
cú pháp
4This is rendered
This is not rendered
Giải thích thêm một chút về các thuộc tính siêu dữ liệu tại đây.
5 vàThis is rendered
This is not rendered
6 đều là các tham số tùy chọn, nhưng tôi sẽ nói nhanh về chúngThis is rendered
This is not rendered
Trong tài liệu của Angular, nó nói rằng nên đặt
5 thành “true để đọc một mã thông báo khác với các phần tử được truy vấn. ” Tuy nhiên, một cách sử dụng thực tế hơn sẽ bao gồm lớp của phần tử mà bạn quan tâmThis is rendered
This is not rendered
Trong bài đăng Stack Overflow này, nó cho biết có thể có một số trường hợp được liên kết với bộ chọn phần tử. Chẳng hạn, đối với mỗi phần tử, có ít nhất một
8 và mộtThis is rendered
This is not rendered
9. Đừng lo lắng nếu bây giờ hai lớp này nghe có vẻ xa lạ với bạn, tôi sẽ đề cập đến lớp sau một chútThis is rendered
This is not rendered
Thuộc tính
import { ..., ComponentFactoryResolver } from '@angular/core';40 đơn giản hơn. Đặt nó thành
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
import { ..., ComponentFactoryResolver } from '@angular/core';41 nếu bạn muốn kết quả truy vấn chạy trước khi phát hiện thay đổi xảy ra
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
Hãy xem một ví dụ để xem cách chúng ta có thể truy cập vào
9 của phần tửThis is rendered
This is not rendered
Ví dụ
7
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
3. Đính kèm Chế độ xem
Bây giờ chúng tôi có thể chọn một phần tử neo, chúng tôi cần đính kèm [các] chế độ xem cho nó.
9 đại diện cho vùng chứa phần tử mà chúng ta có thể đính kèm các khung nhìn sauThis is rendered
This is not rendered
Các phần tử neo
Trong ví dụ trên, chúng tôi đang sử dụng
import { ..., ComponentFactoryResolver } from '@angular/core';44 làm phần tử neo. Ngoài ra, chúng ta cũng có thể sử dụng
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
5. Tôi nghi ngờ một số người sẽ tò mò liệu chúng ta có thể sử dụng các phần tử khác hay không, chẳng hạn như một
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
import { ..., ComponentFactoryResolver } from '@angular/core';46. Về mặt lý thuyết, chúng ta có thể sử dụng bất kỳ yếu tố nào chúng ta muốn
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
Tuy nhiên, điều quan trọng cần lưu ý là Angular không thực sự chèn chế độ xem vào phần tử, mà là sau phần tử được giới hạn bởi
import { ..., ComponentFactoryResolver } from '@angular/core';47
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
Cả
import { ..., ComponentFactoryResolver } from '@angular/core';44 và
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
5 đều không thực sự được hiển thị trong DOM mà thay vào đó, như các nhận xét mà Angular biết để tìm. Như vậy, việc sử dụng các phần tử này cho phép chúng tôi tránh chèn các phần tử thừa vào DOM, chẳng hạn như một
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
import { ..., ComponentFactoryResolver } from '@angular/core';46 không mong muốn
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
Chèn chế độ xem
Trong khối mã trên, chúng tôi đã có một thuộc tính cá thể có tên là
71 và chúng tôi chỉ cần thêm chế độ xem
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
7
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Trước đó, chúng tôi đã sử dụng phương thức
72 từ đối tượng
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
5, nhưng
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
9 có một phương thức nhận vào mộtThis is rendered
This is not rendered
5, tạo chế độ xem máy chủ bằng cách gọi nội bộ hàm
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
76 của nó và tự động chèn chế độ xem
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Truyền dữ liệu cho thành phần động
Ngay bây giờ, chúng tôi có khả năng tự động tạo chế độ xem máy chủ. Một điều hữu ích để có thể làm là chuyển dữ liệu vào thành phần của chúng tôi. Bằng cách đó, chúng tôi có thể tự động tạo chế độ xem máy chủ với dữ liệu động
Hãy xây dựng trên ví dụ trên
1
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Phương thức
77 trả về một đối tượng
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
78 mà chúng ta có thể sử dụng để truy cập thuộc tính thể hiện và thêm khóa
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
79. Bằng cách đó, trong thành phần con của chúng ta, chúng ta có thể chỉ cần tham chiếu tên biến dữ liệu thông qua phép nội suy
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Tạo chế độ xem được nhúng
Bây giờ chúng ta đã biết cách tạo chế độ xem máy chủ, chế độ xem được nhúng gần như tương tự về mặt khái niệm. Nhớ lại rằng chúng ta đã nói về
4 trước đó?
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
6
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
Chúng tôi chỉ cần thêm một thuộc tính đối tượng
4 khác và sử dụng phương thức của
...providers: [],
bootstrap: [AppComponent],
entryComponents: [FirstComponent]
}];
import { ..., ComponentFactoryResolver } from '@angular/core';47 để khởi tạo chế độ xem và chèn nó
import { FirstComponent } from '/firstcomponent.component.ts'...export class ParentComponent implements OnInit {constructor[private resolver: ComponentFactoryResolver] {}
}ngOnInit[] {
const componentFactory = this.resolver.resolveComponentFactory[
FirstComponent];
const dynamicallyCreatedComponent = componentFactory.create[];
}
Từ cuối cùng
Bằng cách hiểu ba khái niệm này, bạn sẽ có thể tạo các chế độ xem động trong Angular một cách dễ dàng
Trong hướng dẫn chính thức, việc tải thành phần động được thực hiện khác hẳn với sự trợ giúp của các chỉ thị. Tôi quyết định nói thêm một chút về việc thực hiện nó mà không có nó vì nó dường như giúp tiết kiệm rắc rối khi tạo chỉ thị. Tuy nhiên, sẽ rất tốt nếu bạn cũng xem các tài liệu chính thức để hiểu các cơ chế cơ bản