จุดประสงค์ของการจัดเตรียมไว้ในมัณฑนากรแบบฉีดเมื่อสร้าง Services ใน Angular 6 คืออะไร?


136

เมื่อสร้างเซอร์วิสใน Angular CLI จะเป็นการเพิ่มข้อมูลเมตาพิเศษด้วยคุณสมบัติ "ให้ไว้ใน" โดยมีค่าเริ่มต้นเป็น "root" สำหรับตัวตกแต่งแบบ Injectable

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

สิ่งที่ให้ไว้ในทำคืออะไร? ฉันสมมติว่านี่เป็นการทำให้บริการพร้อมใช้งานเหมือนบริการซิงเกิลตัน 'ทั่วโลก' สำหรับแอปพลิเคชันทั้งหมดอย่างไรก็ตามจะไม่เป็นการดีกว่าที่จะประกาศบริการดังกล่าวในอาร์เรย์ผู้ให้บริการของ AppModule?

UPDATE:

สำหรับคนอื่นย่อหน้าต่อไปนี้ให้คำอธิบายที่ดีอีกอย่างหนึ่งเช่นกันโดยเฉพาะอย่างยิ่งหากคุณต้องการให้บริการเฉพาะโมดูลคุณลักษณะ

ขณะนี้มีวิธีใหม่ที่แนะนำในการลงทะเบียนผู้ให้บริการภายใน@Injectable()มัณฑนากรโดยตรงโดยใช้providedIn แอตทริบิวต์ใหม่ ยอมรับ'root'เป็นค่าหรือโมดูลใด ๆ ของแอปพลิเคชันของคุณ เมื่อคุณใช้งาน'root'ของคุณinjectableจะถูกลงทะเบียนเป็นซิงเกิลตันในแอปพลิเคชันและคุณไม่จำเป็นต้องเพิ่มให้กับผู้ให้บริการของโมดูลรูท ในทำนองเดียวกันถ้าคุณใช้ providedIn: UsersModuleที่injectableมีการลงทะเบียนเป็นผู้ให้บริการที่UsersModuleไม่ต้องเพิ่มไปยังprovidersของโมดูล." - https://blog.ninja-squad.com/2018/05/04/what-is-new-angular -6 /

อัปเดต 2:

หลังจากการตรวจสอบเพิ่มเติมฉันได้ตัดสินใจว่าจะมีประโยชน์เท่านั้น providedIn: 'root'

หากคุณต้องการprovideใช้บริการในโมดูลอื่นที่ไม่ใช่รูทโมดูลคุณควรใช้providersอาร์เรย์ในมัณฑนากรของโมดูลคุณลักษณะดีกว่ามิฉะนั้นคุณจะต้องพึ่งพาการอ้างอิงแบบวงกลม มีการพูดคุยที่น่าสนใจที่นี่ - https://github.com/angular/angular-cli/issues/10170


17
ฉันคิดว่าการอัปเดตของคุณควรเป็นคำตอบ (คุณสามารถตอบคำถามของคุณเองได้) แทนที่จะเพิ่มลงในคำถามของคุณ
PhoneixS

ส่วนที่สำคัญที่สุดคือ SINGLETON ไม่มีใครพูดถึงมัน!
Kyle Burkett

คำตอบ:


55

หากคุณใช้งานที่ให้มาอินเจ็กต์จะถูกลงทะเบียนเป็นผู้ให้บริการของโมดูลโดยไม่ต้องเพิ่มเข้าไปในผู้ให้บริการของโมดูล

จาก Docs

บริการนี้เป็นคลาสที่ CLI สร้างขึ้นและตกแต่งด้วย @Injectable โดยค่าเริ่มต้นมัณฑนากรนี้ถูกกำหนดค่าด้วยคุณสมบัติที่ให้ไว้ซึ่งสร้างผู้ให้บริการสำหรับบริการ ในกรณีนี้ให้ใน: 'root' ระบุว่าควรให้บริการในหัวฉีดราก


4
ขอบคุณ Sajeetharan โอเคดูเหมือนจะเป็นทางลัดใหม่ในการระบุว่าควรให้บริการที่ไหน ฉันเดาว่าการตั้งค่าเริ่มต้นของฉันน่าจะดูรายชื่อผู้ให้บริการของโมดูลเพื่อดูบริการทั้งหมดที่ประกาศว่าเป็นผู้ให้บริการแทนที่จะดูฐานรหัสที่กระจัดกระจายสำหรับแท็ก ProvidedIn .... (?)
Stefan Zvonar

2
มีเหตุผลใดที่ Angular จะเพิ่มสิ่งนี้? มีปัญหาที่กำลังแก้ไขอยู่หรือไม่? ฉันไม่เห็นว่าจะมีเหตุผลสำหรับเรื่องนี้
prolink007

3
ทำให้นิยาม AppModule / CoreModule เล็กลงเล็กน้อย;)
Stefan Zvonar

22
@ prolink007 การใช้ providedIn ช่วยให้แอปพลิเคชันโหลดแบบขี้เกียจได้ ในการทดสอบสิ่งนี้ให้ใส่บันทึกคอนโซลในบริการของคุณ หน้าแรกของฉันเคยโหลดบริการ 16 รายการตอนนี้โหลดได้ 9 รายการมันยากที่จะหาจำนวนประสิทธิภาพ แต่ฉันรู้สึกดีขึ้นที่รู้ว่าฉันไม่ได้โหลดบริการจนกว่าจะจำเป็น :)
Stevethemacguy

3
คุณสามารถทำให้บริการของคุณสั่นไหวได้โดยใช้providedInแอตทริบิวต์เพื่อกำหนดตำแหน่งที่ควรเริ่มต้นบริการเมื่อใช้@Injectable()มัณฑนากร จากนั้นคุณควรลบออกจากแอตทริบิวต์ผู้ให้บริการของNgModuleการประกาศของคุณรวมถึงคำสั่งนำเข้าสิ่งนี้สามารถช่วยลดขนาดกลุ่มได้โดยการลบโค้ดที่ไม่ได้ใช้ออกจากบันเดิล
nircraft

48

providedIn: 'root' เป็นวิธีที่ง่ายและมีประสิทธิภาพที่สุดในการให้บริการตั้งแต่ Angular 6:

  1. บริการนี้จะพร้อมใช้งานแอปพลิเคชันในรูปแบบซิงเกิลตันโดยไม่จำเป็นต้องเพิ่มลงในอาร์เรย์ผู้ให้บริการของโมดูล (เช่น Angular <= 5)
  2. หากบริการถูกใช้ภายในโมดูลที่โหลดแบบเกียจคร้านระบบจะโหลดโมดูลนั้น
  3. หากไม่เคยใช้งานจะไม่มีอยู่ในบิลด์ (ทรีเชค)

สำหรับข้อมูลเพิ่มเติมโปรดอ่านเอกสารประกอบและคำถามที่พบบ่อยของ NgModule

Btw:

  1. หากคุณไม่ต้องการซิงเกิลตันทั้งแอปพลิเคชันให้ใช้อาร์เรย์ขององค์ประกอบของผู้ให้บริการแทน
  2. หากคุณต้องการ จำกัด ขอบเขตเพื่อไม่ให้นักพัฒนารายอื่นใช้บริการของคุณนอกโมดูลเฉพาะให้ใช้providersอาร์เรย์ของ NgModule แทน

38

จากเอกสาร

มัณฑนากรแบบฉีดคืออะไร?

ทำเครื่องหมายคลาสว่าพร้อมใช้งานสำหรับ Injector สำหรับการสร้าง

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

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

บริการนี้เป็นคลาสที่ CLI สร้างขึ้นและตกแต่งด้วย @Injectable ()

สิ่งที่ให้ไว้ในทำคืออะไร?

กำหนดว่าหัวฉีดใดที่จะให้หัวฉีดได้โดยการเชื่อมโยงกับ @NgModule หรือ InjectorType อื่น ๆ หรือโดยการระบุว่าหัวฉีดนี้ควรจัดเตรียมไว้ในหัวฉีด 'ราก' ซึ่งจะเป็นหัวฉีดระดับแอปพลิเคชันในแอปส่วนใหญ่

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

ให้ใน: 'ราก'

เมื่อคุณให้บริการที่ระดับรูท Angular จะสร้างอินสแตนซ์บริการที่ใช้ร่วมกันเพียงชุดเดียวและแทรกลงในคลาสใด ๆ ที่ขอ การลงทะเบียนผู้ให้บริการในข้อมูลเมตาของ @Injectable () ยังช่วยให้ Angular ปรับแต่งแอปได้โดยการนำบริการออกจากแอปที่คอมไพล์แล้วหากไม่ได้ใช้

ให้ใน: โมดูล

นอกจากนี้ยังสามารถระบุได้ว่าควรให้บริการใน @NgModule โดยเฉพาะ ตัวอย่างเช่นหากคุณไม่ต้องการให้บริการพร้อมใช้งานสำหรับแอปพลิเคชันเว้นแต่จะนำเข้าโมดูลที่คุณสร้างขึ้นคุณสามารถระบุได้ว่าควรให้บริการในโมดูล

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

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

วิธีนี้เป็นที่ต้องการเนื่องจากเปิดใช้งานการเขย่าต้นไม้ (การเขย่าต้นไม้เป็นขั้นตอนในกระบวนการสร้างที่ลบรหัสที่ไม่ได้ใช้ออกจากฐานรหัส ) ของบริการหากไม่มีสิ่งใดแทรกเข้าไป

หากไม่สามารถระบุในบริการได้ว่าควรให้โมดูลใดคุณสามารถประกาศผู้ให้บริการภายในโมดูลได้:

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

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

4
คำอธิบายที่ดีที่สุด
nop

2
คำตอบนี้ดีกว่าคำจำกัดความในเอกสารเชิงมุม ชัดเจนมาก
Shameera Anuranga

2
อธิบายได้ดีมากขอบคุณมาก!
Zaki Mohammed

แล้วเวลาว่าง@Injectable()ล่ะเช่น?
Ben Taliadoros

13

providedIn บอก Angular ว่า root หัวฉีดมีหน้าที่สร้างอินสแตนซ์ของบริการของคุณ บริการที่ให้ด้วยวิธีนี้จะพร้อมใช้งานโดยอัตโนมัติสำหรับแอปพลิเคชันทั้งหมดและไม่จำเป็นต้องระบุไว้ในโมดูลใด ๆ

ชั้นเรียนบริการสามารถทำหน้าที่เป็นผู้ให้บริการของตนเองซึ่งเป็นเหตุผลว่าทำไมการกำหนดไว้ในมัณฑนากร @Injectable จึงเป็นการลงทะเบียนทั้งหมดที่คุณต้องการ


4

ตามDocumentation:

การลงทะเบียนผู้ให้บริการในข้อมูลเมตาของ @Injectable () ยังช่วยให้ Angular ปรับแต่งแอปได้โดยการนำบริการออกจากแอปที่คอมไพล์แล้วหากไม่ได้ใช้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.