Sự khác biệt giữa khai báo, nhà cung cấp và nhập khẩu trong NgModule là gì?


Câu trả lời:


516

Khái niệm góc cạnh

  • imports làm cho các khai báo xuất của các mô-đun khác có sẵn trong mô-đun hiện tại
  • declarationslà để làm cho các chỉ thị (bao gồm các thành phần và đường ống) từ mô-đun hiện tại có sẵn cho các chỉ thị khác trong mô-đun hiện tại. Bộ chọn chỉ thị, thành phần hoặc đường ống chỉ được khớp với HTML nếu chúng được khai báo hoặc nhập.
  • providerslà để làm cho các dịch vụ và giá trị được biết đến với DI (tiêm phụ thuộc). Chúng được thêm vào phạm vi gốc và chúng được đưa vào các dịch vụ hoặc chỉ thị khác có chúng là phụ thuộc.

Một trường hợp đặc biệt cho providerscác mô-đun được tải lười biếng có được trình tiêm con riêng của chúng. providerscủa một mô-đun tải lười biếng chỉ được cung cấp cho mô-đun tải lười biếng này theo mặc định (không phải toàn bộ ứng dụng như với các mô-đun khác).

Để biết thêm chi tiết về các mô-đun, hãy xem https://angular.io/docs/ts/latest/guide/ngmodule.html

  • exportslàm cho các thành phần, chỉ thị và đường ống có sẵn trong các mô-đun thêm mô-đun này vào imports. exportscũng có thể được sử dụng để xuất lại các mô-đun như CommonModule và FormsModule, thường được thực hiện trong các mô-đun chia sẻ.

  • entryComponentsđăng ký các thành phần để biên dịch ngoại tuyến để chúng có thể được sử dụng với ViewContainerRef.createComponent(). Các thành phần được sử dụng trong cấu hình bộ định tuyến được thêm vào ngầm.

Nhập khẩu TypeScript (ES2015)

import ... from 'foo/bar'( có thể giải quyết thành mộtindex.ts ) dành cho nhập TypeScript. Bạn cần những thứ này bất cứ khi nào bạn sử dụng mã định danh trong tệp bản thảo được khai báo trong tệp bản in khác.

Angular's @NgModule() importsvà TypeScript importlà hai khái niệm hoàn toàn khác nhau .

Xem thêm jDriven - Cú pháp nhập kiểu TypeScript và ES6

Hầu hết trong số chúng thực sự là cú pháp mô-đun ECMAScript 2015 (ES6) đơn giản mà TypeScript cũng sử dụng.


1
Tôi nghĩ, nhưng tôi không chắc chắn, khuyến nghị mới nhất là đưa các nhà cung cấp toàn ứng dụng vào CoreModule, thay vì sử dụng forRoot()trong một mô-đun tải lười biếng. Bạn có đồng ý không? Xem Mô-đun lõi . Liên kết đến # shared-module-for-root không còn tồn tại.
Mark Rajcok

1
Giải thích tuyệt vời. Cảm ơn bạn, @ günter-zöchbauer. Chỉ đề cập đến việc afaik importlà một chức năng JS (ES2015), không phải là một TypeScript. :)
cassi.lup

và xuất khẩu [] trong NgModule như xuất khẩu là gì: [MatCheckBox]
Omar được trả tiền vào

4
Thành thật mà nói, tôi nghĩ rằng thiết kế của NgModule of Angular là vụng về và tối nghĩa so với VueReact . Bạn cần nhập mô-đun khác với imports, nhưng xuất các khai báo của bạn (thành phần, chỉ thị, đường ống) với exports. Vì vậy, các mục tiêu chính của importsexportslà những thứ khác nhau. Thay vào đó, mục tiêu chính exportslà của bạn declarations. Bạn khai báo thành phần của mình bằng declarations, nhưng đối với thành phần được tải động, bạn cần đặt chúng vào entryComponents. Trong khi đó, providersDI được quản lý trong một câu chuyện khác bởi DI.
xuemind

1
một câu trả lời phức tạp mô tả một khuôn khổ phức tạp
Donato

85

imports được sử dụng để nhập các mô-đun hỗ trợ như FormsModule, RouterModule, CommonModule hoặc bất kỳ mô-đun tính năng tùy chỉnh nào khác.

declarationsđược sử dụng để khai báo các thành phần, chỉ thị, đường ống thuộc về mô-đun hiện tại. Mọi người bên trong khai báo đều biết nhau. Ví dụ: nếu chúng ta có một thành phần, giả sử UsernameComponent, hiển thị danh sách tên người dùng và chúng ta cũng có một đường ống, giả sử toupperPipe, chuyển đổi một chuỗi thành chuỗi ký tự viết hoa. Bây giờ Nếu chúng tôi muốn hiển thị tên người dùng bằng chữ in hoa trong UsernameComponent thì chúng tôi có thể sử dụng toupperPipe mà chúng tôi đã tạo trước đây nhưng câu hỏi là làm thế nào UsernameComponent biết rằng toupperPipe tồn tại và làm thế nào nó có thể truy cập và sử dụng nó. Ở đây có các khai báo, chúng ta có thể khai báo UsernameComponent và toupperPipe.

Providers được sử dụng để tiêm các dịch vụ theo yêu cầu của các thành phần, chỉ thị, đường ống trong mô-đun.


3
"khai báo: được sử dụng để khai báo các thành phần, chỉ thị, đường ống thuộc về mô-đun hiện tại. Mọi thứ bên trong khai báo đều biết nhau." đây phải là câu trả lời được chấp nhận
Deen John

60

Các thành phần được khai báo, Mô-đun được nhập và Dịch vụ được cung cấp. Một ví dụ tôi đang làm việc với:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';


import { AppComponent } from './app.component';
import {FormsModule} from '@angular/forms';
import { UserComponent } from './components/user/user.component';
import { StateService } from './services/state.service';    

@NgModule({
  declarations: [
    AppComponent,
    UserComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [ StateService ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

3
Tôi thích sự đơn giản của lời giải thích này, nhưng nó khiến tôi tự hỏi tại sao không chỉ có một thuộc tính "Stuffs ThisComponentNeed"? Có vẻ như tất cả họ đều đang xử lý cùng một thứ, điều này làm cho các đoạn mã khác có sẵn cho thành phần hiện tại.
redOc / 1013

1
@ redOc / 1013 Tôi đồng ý. Ví dụ, trong Node.js, mọi thứ đều được nhập theo cùng một cách bất kể đó là Mô hình DB, mô-đun, dịch vụ hoặc gói bên thứ 3 đã cài đặt. Và tôi nghĩ điều tương tự cũng xảy ra với ReacJS
SanSolo

18

@NgModuleCấu trúc góc :

  1. import { x } from 'y';: Đây là cú pháp bản thảo tiêu chuẩn ( ES2015/ES6cú pháp mô-đun) để nhập mã từ các tệp khác. Đây không phải là cụ thể góc . Ngoài ra, đây về mặt kỹ thuật không phải là một phần của mô-đun, chỉ cần lấy mã cần thiết trong phạm vi của tệp này.
  2. imports: [FormsModule]: Bạn nhập các mô-đun khác vào đây. Ví dụ chúng tôi nhập FormsModuletrong ví dụ dưới đây. Bây giờ chúng ta có thể sử dụng chức năng mà FormsModule phải cung cấp trong suốt mô-đun này.
  3. declarations: [OnlineHeaderComponent, ReCaptcha2Directive]: Bạn đặt các thành phần, chỉ thị và đường ống của bạn ở đây. Sau khi khai báo ở đây, bây giờ bạn có thể sử dụng chúng trong toàn bộ mô-đun. Ví dụ bây giờ chúng ta có thể sử dụng OnlineHeaderComponenttrong AppComponentview (file html). Angular biết nơi để tìm thấy điều này OnlineHeaderComponentbởi vì nó được khai báo trong @NgModule.
  4. providers: [RegisterService]: Ở đây các dịch vụ của chúng tôi về mô-đun cụ thể này được xác định. Bạn có thể sử dụng các dịch vụ trong các thành phần của mình bằng cách tiêm chích phụ thuộc.

Mô-đun ví dụ:

// Angular
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

// Components
import { AppComponent } from './app.component';
import { OfflineHeaderComponent } from './offline/offline-header/offline-header.component';
import { OnlineHeaderComponent } from './online/online-header/online-header.component';

// Services
import { RegisterService } from './services/register.service';

// Directives
import { ReCaptcha2Directive } from './directives/re-captcha2.directive';

@NgModule({
  declarations: [
    OfflineHeaderComponent,,
    OnlineHeaderComponent,
    ReCaptcha2Directive,
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
  ],
  providers: [
    RegisterService,
  ],
  entryComponents: [
    ChangePasswordComponent,
    TestamentComponent,
    FriendsListComponent,
    TravelConfirmComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

10

Thêm một bảng cheat nhanh có thể giúp ích sau thời gian nghỉ dài với Angular:


KHAI THÁC

Thí dụ:

declarations: [AppComponent]

Chúng ta có thể tiêm gì ở đây? Linh kiện, ống dẫn, chỉ thị


Nhập khẩu

Thí dụ:

imports: [BrowserModule, AppRoutingModule]

Chúng ta có thể tiêm gì ở đây? các mô-đun khác


CUNG CẤP

Thí dụ:

providers: [UserService]

Chúng ta có thể tiêm gì ở đây? dịch vụ


BOOTSTRAP

Thí dụ:

bootstrap: [AppComponent]

Chúng ta có thể tiêm gì ở đây? thành phần chính sẽ được tạo bởi mô-đun này (nút cha trên cùng cho cây thành phần)


THÀNH PHẦN NHẬP

Thí dụ:

entryComponents: [PopupComponent]

Chúng ta có thể tiêm gì ở đây? các thành phần được tạo động (ví dụ: bằng cách sử dụng ViewContainerRef.createComponent ())


XUẤT KHẨU

Thí dụ:

export: [TextDirective, PopupComponent, BrowserModule]

Chúng ta có thể tiêm gì ở đây? các thành phần, chỉ thị, mô-đun hoặc đường ống mà chúng tôi muốn có quyền truy cập vào chúng trong một mô-đun khác (sau khi nhập mô-đun này)


1
Còn xuất khẩu thì sao?
lugte098

@ lugte098 Tôi đã thêm xuất vào danh sách này
Przemek Struciński

Tôi thích cách bố trí này để giải thích, rất dễ tiêu hóa. Cảm ơn!
Aaron Jordan

1
  1. khai báo : Thuộc tính này nói về các Thành phần, Chỉ thị và Đường ống thuộc về mô-đun này.
  2. xuất khẩu : Tập hợp con của các khai báo sẽ hiển thị và có thể sử dụng được trong các mẫu thành phần của các NgModules khác.
  3. nhập khẩu : Các mô-đun khác có lớp xuất khẩu là cần thiết bởi các mẫu thành phần được khai báo trong NgModule này.
  4. nhà cung cấp : Người tạo ra các dịch vụ mà NgModule này đóng góp cho bộ sưu tập dịch vụ toàn cầu; chúng có thể truy cập được trong tất cả các phần của ứng dụng. (Bạn cũng có thể chỉ định nhà cung cấp ở cấp thành phần, thường được ưu tiên.)
  5. bootstrap : Khung nhìn ứng dụng chính, được gọi là thành phần gốc, lưu trữ tất cả các khung nhìn ứng dụng khác. Chỉ NgModule gốc mới nên đặt thuộc tính bootstrap.
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.