Mục đích của việc cung cấp với Trình trang trí tiêm khi tạo Dịch vụ trong Angular 6 là gì?


136

Khi tạo các dịch vụ trong CLI góc, nó sẽ thêm siêu dữ liệu bổ sung với thuộc tính 'được cung cấp trong' với mặc định là 'root' cho trình trang trí Tiêm.

@Injectable({
  providedIn: 'root',
})

Chính xác thì cung cấp những gì? Tôi giả định rằng điều này sẽ làm cho dịch vụ khả dụng như một dịch vụ đơn loại 'toàn cầu' cho toàn bộ ứng dụng, tuy nhiên, sẽ không sạch hơn khi khai báo các dịch vụ đó trong mảng nhà cung cấp của AppModule?

CẬP NHẬT:

Đối với bất kỳ ai khác, đoạn sau đây cũng cung cấp một lời giải thích tốt khác về nó, đặc biệt nếu bạn muốn cung cấp dịch vụ của mình cho một mô-đun tính năng.

Hiện tại có một cách mới, được đề nghị, để đăng ký một nhà cung cấp, trực tiếp bên trong @Injectable()trang trí, sử dụng providedIn thuộc tính mới . Nó chấp nhận 'root'như một giá trị hoặc bất kỳ mô-đun nào trong ứng dụng của bạn. Khi bạn sử dụng 'root', bạn injectablesẽ được đăng ký dưới dạng một đơn trong ứng dụng và bạn không cần thêm nó vào các nhà cung cấp của mô-đun gốc. Tương tự, nếu bạn sử dụng providedIn: UsersModule, thì injectableđược đăng ký là nhà cung cấp UsersModulemà không cần thêm nó vào providersmô-đun. "- https://blog.ninja-squad.com/2018/05/04/what-is-new-angular -6 /

CẬP NHẬT 2:

Sau khi điều tra thêm, tôi đã quyết định rằng nó chỉ hữu ích để có providedIn: 'root'

Nếu bạn muốn providemột dịch vụ trong bất kỳ mô-đun nào khác ngoài mô-đun gốc, thì tốt hơn hết bạn nên sử dụng providersmảng trong các trang trí của mô-đun tính năng, nếu không, bạn sẽ gặp khó khăn với các phụ thuộc vòng tròn. Các cuộc thảo luận thú vị sẽ có tại đây - https://github.com/angular/angular-cli/issues/10170


17
Tôi nghĩ rằng các cập nhật của bạn nên là một câu trả lời (bạn có thể trả lời câu hỏi của riêng bạn) thay vì thêm nó vào câu hỏi của bạn.
PhoneixS

Phần quan trọng nhất là SINGLETON, không ai đề cập đến nó!
Kyle Burkett

Câu trả lời:


54

nếu bạn sử dụng được cung cấp, thì tiêm được đăng ký là nhà cung cấp Mô-đun mà không cần thêm nó vào nhà cung cấp mô-đun.

Từ Docs

Bản thân dịch vụ là một lớp mà CLI đã tạo và được trang trí bằng @Injectable. Theo mặc định, trình trang trí này được cấu hình với thuộc tính được cung cấp, tạo ra một nhà cung cấp cho dịch vụ. Trong trường hợp này, được cung cấpIn: 'root' chỉ định rằng dịch vụ sẽ được cung cấp trong trình tiêm gốc.


4
Cảm ơn Sajeetharan. Được rồi, có vẻ như đó là một cách tắt mới để chỉ định nơi dịch vụ sẽ được cung cấp. Tôi đoán sở thích ban đầu của tôi sẽ xem xét danh sách nhà cung cấp của mô-đun để xem tất cả các dịch vụ được khai báo là nhà cung cấp, thay vì sử dụng cơ sở mã phân tán cho các thẻ được cung cấp .... (?)
Stefan Zvonar

2
Có bất kỳ lý do cho Angular để thêm điều này? Có một vấn đề này là giải quyết? Tôi không thấy có một lý do cho việc này.
prolink007

3
Giữ định nghĩa AppModule / CoreModule nhỏ hơn một chút;)
Stefan Zvonar

22
@ prolink007. Sử dụng cung cấpIn cho phép các dịch vụ được tải nhanh bởi ứng dụng. Để kiểm tra điều này, hãy đặt nhật ký giao diện điều khiển trong các dịch vụ của bạn. Trang chủ của tôi đã từng tải 16 dịch vụ, giờ nó tải 9. Thật khó để định lượng hiệu suất, nhưng tôi cảm thấy tốt hơn khi biết rằng tôi không tải dịch vụ cho đến khi chúng cần :).
Stevethemacguy

3
Bạn có thể làm cho dịch vụ của mình có thể chuyển đổi được bằng cách sử dụng providedInthuộc tính để xác định nơi dịch vụ sẽ được khởi tạo khi sử dụng trình @Injectable()trang trí. Sau đó, bạn nên xóa nó khỏi thuộc tính nhà cung cấp của NgModulekhai báo cũng như câu lệnh nhập của nó. Điều này có thể giúp giảm kích thước gói bằng cách xóa mã không sử dụng khỏi gói.
nircraft

48

providedIn: 'root' là cách dễ nhất và hiệu quả nhất để cung cấp dịch vụ kể từ Angular 6:

  1. Dịch vụ này sẽ có sẵn ứng dụng rộng rãi dưới dạng đơn lẻ mà không cần thêm nó vào mảng nhà cung cấp của mô-đun (như Angular <= 5).
  2. Nếu dịch vụ chỉ được sử dụng trong một mô-đun được tải lười biếng, nó sẽ được tải lười biếng với mô-đun đó
  3. Nếu nó không bao giờ được sử dụng, nó sẽ không được chứa trong bản dựng (cây bị rung).

Để biết thêm thông tin, hãy xem xét việc đọc tài liệuCâu hỏi thường gặp về NgModule

Btw:

  1. Nếu bạn không muốn một singleton trên toàn ứng dụng, hãy sử dụng mảng của nhà cung cấp thay thế.
  2. Nếu bạn muốn giới hạn phạm vi để không có nhà phát triển nào khác sử dụng dịch vụ của bạn ngoài một mô-đun cụ thể, hãy sử dụng providersmảng NgModule thay thế.

37

Từ Tài liệu

Trang trí tiêm là gì?

Đánh dấu một lớp là có sẵn để In phun để tạo.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

Bản thân dịch vụ là một lớp mà CLI đã tạo và được trang trí bằng @Injectable ().

Chính xác thì cung cấp những gì?

Xác định công cụ tiêm nào sẽ cung cấp cho người tiêm, bằng cách liên kết nó với @NgModule hoặc InjectionType khác, hoặc bằng cách chỉ định rằng công cụ tiêm này nên được cung cấp trong công cụ tiêm 'root', sẽ là công cụ tiêm cấp ứng dụng trong hầu hết các ứng dụng.

providedIn: Type<any> | 'root' | null

cung cấp trong: 'root'

Khi bạn cung cấp dịch vụ ở cấp gốc, Angular tạo một thể hiện dịch vụ chung, duy nhất và đưa nó vào bất kỳ lớp nào yêu cầu. Đăng ký nhà cung cấp trong siêu dữ liệu @Injectable () cũng cho phép Angular tối ưu hóa một ứng dụng bằng cách xóa dịch vụ khỏi ứng dụng đã biên dịch nếu không sử dụng.

cung cấp trong: Mô-đun

Cũng có thể chỉ định rằng một dịch vụ nên được cung cấp trong một @NgModule cụ thể. Ví dụ: nếu bạn không muốn dịch vụ có sẵn cho các ứng dụng trừ khi họ nhập mô-đun bạn đã tạo, bạn có thể chỉ định rằng dịch vụ sẽ được cung cấp trong mô-đun

import { Injectable } from '@angular/core';
import { UserModule } from './user.module';

@Injectable({
  providedIn: UserModule,
})
export class UserService {
}

Phương pháp này được ưa thích vì nó cho phép Lắc cây (Lắc cây là một bước trong quy trình xây dựng để loại bỏ mã không sử dụng khỏi cơ sở mã ) của dịch vụ nếu không có gì tiêm vào nó.

Nếu không thể chỉ định trong dịch vụ nên cung cấp mô-đun nào, bạn cũng có thể khai báo nhà cung cấp dịch vụ trong mô-đun:

import { NgModule } from '@angular/core';
import { UserService } from './user.service';

@NgModule({
  providers: [UserService],
})
export class UserModule {
}

4
Giải thích tốt nhất.
nop

2
Câu trả lời này tốt hơn định nghĩa trong tài liệu góc. rất rõ ràng.
Shameera Anuranga

2
Giải thích rất tốt, Cảm ơn rất nhiều!
Zaki Mohammed

Thế còn khi nó trống, chẳng hạn như @Injectable()?
Ben Taliadoros

13

cung cấp cho Angular rằng người tiêm gốc có trách nhiệm tạo một phiên bản của Dịch vụ của bạn. Các dịch vụ được cung cấp theo cách này sẽ tự động được cung cấp cho toàn bộ ứng dụng và không cần phải liệt kê trong bất kỳ mô-đun nào.

Các lớp dịch vụ có thể đóng vai trò là nhà cung cấp của chính họ, đó là lý do tại sao việc xác định chúng trong trình trang trí @Injectable là tất cả các đăng ký bạn cần.


4

Theo Documentation:

Đăng ký nhà cung cấp trong siêu dữ liệu @Injectable () cũng cho phép Angular tối ưu hóa một ứng dụng bằng cách xóa dịch vụ khỏi ứng dụng đã biên dịch nếu không sử dụng.

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.