EntryComponents trong ngModule góc là gì?


131

Tôi đang làm việc trên một Ionicứng dụng ( 2.0.0-rc0) phụ thuộc vào angular 2. Vì vậy, giới thiệu mới ngModulesđược bao gồm. Tôi đang thêm app.module.ts.dưới đây của tôi .

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { Users } from '../pages/users/users';

@NgModule({
  declarations: [
    MyApp,
    Users
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    Users
  ]
})
export class AppModule {}

Làm gì entryComponentsở đây? Componentsđã được xác định trong declarations. Vì vậy, những gì cần thiết để lặp lại chúng? Điều gì sẽ xảy ra nếu tôi không bao gồm một thành phần ở đây?


4
Angular sử dụng entryComponents để kích hoạt "cây rung" tức là chỉ biên dịch các thành phần thực sự được sử dụng trong dự án thay vì biên dịch tất cả các thành phần có declaredtrong ngModulenhưng không bao giờ được sử dụng. angular.io/docs/ts/latest/cookbook/ các thành phần nhập cảnh -
Samar

Câu trả lời:


155

Điều này là cho các thành phần được thêm động được thêm vào bằng cách sử dụng ViewContainerRef.createComponent(). Thêm chúng để báo entryComponentscho trình biên dịch mẫu ngoại tuyến để biên dịch chúng và tạo các nhà máy cho chúng.

Các thành phần được đăng ký trong cấu hình tuyến đường cũng được thêm tự động entryComponentsrouter-outletcũng sử dụng ViewContainerRef.createComponent()để thêm các thành phần được định tuyến vào DOM.

Trình biên dịch mẫu ngoại tuyến (OTC) chỉ xây dựng các thành phần thực sự được sử dụng. Nếu các thành phần không được sử dụng trực tiếp trong các mẫu, OTC không thể biết liệu chúng có cần được biên dịch hay không. Với entryComponents, bạn có thể yêu cầu OTC biên dịch các thành phần này để chúng có sẵn khi chạy.

Một thành phần nhập cảnh là gì? (góc cạnh)

Tài liệu NgModule (angular.io)

Xác định các thành phần nên được biên dịch khi thành phần này được xác định. Đối với mỗi thành phần được liệt kê ở đây, Angular sẽ tạo ra một PartFactory và lưu trữ nó trong ElementFactoryResolver.

Nếu bạn không liệt kê một thành phần được thêm động cho entryComponentsbạn sẽ nhận được thông báo lỗi, hãy bỏ qua một nhà máy bị thiếu vì Angular sẽ không tạo ra một thành phần.

Xem thêm https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html


12
Thẳng thắn mà nói, tôi biết câu trả lời đúng 100% của nó nhưng đã đi bouncer cho tôi, bạn có thể vui lòng giải thích thêm không?
Pankaj Parkar

26
Khó có thể nói những gì không rõ ràng. Trình biên dịch mẫu ngoại tuyến (OTC) chỉ xây dựng các thành phần thực sự được sử dụng. Nếu các thành phần không được sử dụng trực tiếp trong các mẫu, OTC không thể biết liệu chúng có cần được biên dịch hay không. Với entryComponentsbạn có thể yêu cầu OTC biên dịch các thành phần này để chúng có sẵn trong thời gian chạy.
Günter Zöchbauer

3
stackoverflow.com/questions/36325212/ sẽ là một ví dụ như vậy
Günter Zöchbauer

2
Vì vậy, nói chung, nếu thành phần được liệt kê trong declarationsnó cũng nên được liệt kê trong entryComponents, phải không?
omnomnom

1
chỉ khi một thành phần được thêm động với createComponentmã của bạn hoặc ví dụ bộ định tuyến cũng sử dụng API thod để thêm các thành phần.
Günter Zöchbauer

30

Bạn sẽ không nhận được lời giải thích tốt hơn các tài liệu Angular: mục nhập thành phầnngmodule-faq .

Và dưới đây là lời giải thích từ các tài liệu góc cạnh.

Một thành phần đầu vào là bất kỳ thành phần nào mà Angular tải bắt buộc theo loại.

Một thành phần được tải khai báo qua bộ chọn của nó không phải là thành phần nhập.

Hầu hết các thành phần ứng dụng được tải khai báo. Angular sử dụng bộ chọn của thành phần để xác định vị trí phần tử trong mẫu. Sau đó, nó tạo ra biểu diễn HTML của thành phần và chèn nó vào DOM tại phần tử được chọn. Đây không phải là thành phần nhập cảnh.

Một vài thành phần chỉ được tải động và không bao giờ được tham chiếu trong mẫu thành phần.

Root bootstrapping AppComponentlà một thành phần nhập cảnh. Đúng, bộ chọn của nó khớp với thẻ phần tử trong index.html. Nhưng index.htmlkhông phải là một mẫu thành phần và AppComponentbộ chọn không khớp với một phần tử trong bất kỳ mẫu thành phần nào.

Tải trọng góc AppComponent một cách linh hoạt bởi vì nó được liệt kê theo loại trong @NgModule.bootstraphoặc được tăng cường bắt buộc với phương thức ngDoBootstrap của mô-đun.

Các thành phần trong định nghĩa tuyến đường cũng là các thành phần nhập cảnh. Một định nghĩa tuyến đường đề cập đến một thành phần theo loại của nó. Bộ định tuyến bỏ qua bộ chọn của thành phần được định tuyến (nếu nó thậm chí có một) và tải động thành phần đó vào một RouterOutlet.

Trình biên dịch không thể khám phá các thành phần mục nhập này bằng cách tìm kiếm chúng trong các mẫu thành phần khác. Bạn phải nói với họ về họ bằng cách thêm họ vào entryComponentsdanh sách.

Angular tự động thêm các loại thành phần sau vào mô-đun entryComponents:

  • Các thành phần trong @NgModule.bootstrapdanh sách.
  • Các thành phần được tham chiếu trong cấu hình bộ định tuyến.

Bạn không cần phải đề cập rõ ràng đến các thành phần này, mặc dù làm như vậy là vô hại.


Ngay bây giờ các tài liệu góc cạnh không có sẵn, vì vậy cảm ơn SO vì điều đó!
Caelum

Điều này dường như không đề cập đến việc các thành phần trong cấu hình tuyến đường được tự động thêm vào entryComponents (vì vậy bạn thường không bao giờ cần phải xác định nó).
Connor

Nếu chúng ta tạo một thành phần được sử dụng như là một EntryComponentchúng ta nên loại bỏ selectorthuộc tính? (vì nó sẽ không được sử dụng)
Ronan

24

Các câu trả lời khác đề cập đến điều này nhưng tóm tắt cơ bản là:

  • cần thiết khi Thành phần KHÔNG được sử dụng trong mẫu html <my-component />
  • Ví dụ: khi sử dụng các thành phần hộp thoại Angular Material, bạn sử dụng thành phần gián tiếp.

Các thành phần hộp thoại vật liệu được tạo bên trong mã TS chứ không phải mẫu:

    const dialogRef = this.dialog.open(MyExampleDialog, { width: '250px' });
  }

Điều này đòi hỏi bạn phải đăng ký nó như là một entryComponent:

  • entryComponents: [MyExampleDialog]

Nếu không, bạn nhận được một lỗi:

  • ERROR Error: No component factory found for MyExampleDialog. Did you add it to @NgModule.entryComponents?

2
Giải thích tốt nhất ở đây.
nop

3

Mảng entryComponents được sử dụng để chỉ xác định các thành phần không được tìm thấy trong html và được tạo động. Angular yêu cầu gợi ý này để tìm thành phần nhập cảnh và biên dịch chúng.

Có hai loại thành phần chính:

  • Các thành phần gốc bootstrapping.
  • Một thành phần bạn chỉ định trong một định nghĩa tuyến đường.

Để biết thêm thông tin chi tiết về các thành phần nhập cảnh, vui lòng tham khảo angular.io https://angular.io/guide/entry-components


1

Một chút nền tảng về entryComponent

entryComponentlà bất kỳ thành phần tải trọng góc bắt buộc. Bạn có thể khai báo entryComponentbằng cách bootstrapping nó trong NgModulehoặc trong định nghĩa tuyến đường.

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent] // bootstrapped entry component
})

Tài liệu nói dưới đây

Để tương phản hai loại thành phần, có những thành phần được bao gồm trong mẫu, đó là khai báo. Ngoài ra, có những thành phần mà bạn tải bắt buộc; đó là, các thành phần nhập cảnh.

Bây giờ để trả lời câu hỏi cụ thể của bạn về entryComponents

entryComponentsmảng trong @NgModuletập tin. Bạn có thể sử dụng điều này để thêm entryComponentsnếu thành phần được bootstrapping bằng cách sử dụng ViewContainerRef.createComponent().

Đó là bạn đang tạo các thành phần một cách linh hoạt chứ không phải bằng bootstrapping hoặc trong mẫu.

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(myComp.component);
const viewContainerRef = this.compHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);

0

Kể từ Angular 9 entryComponents không còn cần thiết nữa nhờ Ivy cho phép tính năng này không được chấp nhận và do đó có thể được xóa khỏi khai báo mô-đun.

Các API và tính năng không dùng nữa - entryComponentsANALYZE_FOR_ENTRY_COMPONENTSkhông còn bắt buộc

Trước đây, entryComponentsmảng trong NgModuleđịnh nghĩa được sử dụng để báo cho trình biên dịch những thành phần nào sẽ được tạo và chèn động. Với Ivy, đây không còn là một yêu cầu nữa và entryComponentsmảng có thể được loại bỏ khỏi các khai báo mô-đun hiện có. Điều tương tự áp dụng cho ANALYZE_FOR_ENTRY_COMPONENTSmã thông báo tiêm.

Ivy góc

Ivy là tên mã cho đường ống biên dịch và kết xuất thế hệ tiếp theo của Angular. Với phiên bản 9 của Angular, trình biên dịch và hướng dẫn thời gian chạy mới được sử dụng theo mặc định thay vì trình biên dịch và thời gian chạy cũ hơn, được gọi là View Engine.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.