Яка мета надається In з декоратором для ін'єкцій при створенні Служб у кутовій 6?


136

Під час генерації сервісів у Angular CLI він додає додаткові метадані з властивістю "наданий в" із замовчуванням "root" для декоратора ін'єкцій.

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

Що саме робиться за умови? Я припускаю, що це робить послугу доступною як "глобальний" тип одиночного типу для всієї програми, однак, чи не буде чистішим заявляти про такі послуги в масиві постачальників AppModule?

ОНОВЛЕННЯ:

Для всіх інших, наступний параграф дав ще одне добре пояснення цього, зокрема, якщо ви хочете надати свою послугу лише модулю функцій.

Зараз існує новий, рекомендований спосіб зареєструвати постачальника, безпосередньо всередині @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/isissue/10170


17
Я думаю, що ваші оновлення повинні бути відповіддю (ви можете відповісти на власні запитання), а не додавати його до свого питання.
PhoneixS

Найважливіша частина - SINGLETON, про це ніхто не згадує!
Кайл Беркетт

Відповіді:


54

якщо ви користуєтеся програмою predviIn, ін'єкційний зареєстрований як постачальник модуля без додавання його до постачальників модуля.

З Docs

Сама послуга - це клас, який створив CLI і прикрашений @Injectable. За замовчуванням цей декоратор налаштований із властивістю надаєтьсяIn, яка створює постачальника послуги. У цьому випадку, якщоIn: 'root' вказує, що послуга повинна надаватися в кореневому інжекторі.


4
Спасибі Саджетаран. Гаразд, так здається, що це новий спосіб швидкого вказівки, де потрібно надавати послугу. Я думаю, що мої первісні переваги були б переглядом списку постачальників модулів, щоб побачити всі послуги, які оголошені постачальниками, а не переслідувати розпорошену базу коду для тегів ProvidedIn .... (?)
Стефан Звонар

2
Чи була якась причина для Angular додати це? Чи є проблема, яку це вирішує? Я не бачу, що в цьому є причина.
prolink007

3
Зберігає визначення AppModule / CoreModule трохи меншим;)
Стефан Звонар

22
@ prolink007. Використання наданих даних дає змогу послугам завантажуватися додатком. Щоб перевірити це, введіть журнали консолей у свої служби. Моя домашня сторінка використовувала для завантаження 16 сервісів, зараз вона завантажує 9. Важко оцінити продуктивність, але я почуваю себе краще, знаючи, що я не завантажую послуги, поки вони не знадобляться :).
Stevethemacguy

3
Ви можете зробити свої послуги струшуючими деревами, використовуючи providedInатрибут, щоб визначити, де послуга повинна бути ініціалізована під час використання @Injectable()декоратора. Тоді вам слід видалити його з атрибута постачальника вашої NgModuleдекларації, а також з його заяви про імпорт. Це може допомогти зменшити розмір пакета, видаливши невикористаний код із пакета.
nircraft

48

providedIn: 'root' це найпростіший та найефективніший спосіб надання послуг з моменту кутового 6:

  1. Послуга буде доступна у всьому додатку у вигляді одиночної форми без необхідності додавати її до масиву постачальників модулів (наприклад, Angular <= 5).
  2. Якщо послуга використовується лише в межах ледачого завантаженого модуля, вона буде ледачо завантажена цим модулем
  3. Якщо він ніколи не використовується, він не міститиметься в збірці (струшене дерево).

Для отримання додаткової інформації врахуйте, прочитавши документацію та поширені запитання NgModule

Btw:

  1. Якщо ви не хочете, щоб один сингл для додатків використовував натомість масив постачальника компонентів.
  2. Якщо ви хочете обмежити область, щоб жоден інший розробник ніколи не використовував вашу послугу за межами певного модуля, скористайтеся providersнатомість масивом NgModule.

37

Від Док

Що таке декоратор для ін'єкцій?

Позначає клас доступним для створення інжектора для створення.

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

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

Сама послуга - це клас, який створив CLI і прикрашений @Injectable ().

Що саме робиться за умови?

Визначає, які інжектори надаватимуть ін'єкційний, або асоціюючи його з @NgModule або іншим InjectorType, або уточнюючи, що цей ін'єкційний інжектор повинен бути наданий у «кореневому» інжекторі, який буде інжектором рівня застосування у більшості програм.

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

за умови: 'root'

Коли ви надаєте послугу на кореневому рівні, Angular створює єдиний спільний екземпляр служби та вводить її в будь-який клас, який вимагає. Реєстрація постачальника у метаданих @Injectable () також дозволяє Angular оптимізувати додаток, видаливши службу зі складеного додатка, якщо він не використовується.

надається в: Модуль

Можна також вказати, що послуга повинна надаватися в певному @NgModule. Наприклад, якщо ви не хочете, щоб послуга була доступною для програм, якщо вони не імпортують створений вами модуль, ви можете вказати, що послуга повинна надаватися в модулі

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

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

Цей спосіб є кращим, оскільки він дозволяє Tree-shaking ( Tresing дерева - це крок у процесі збирання, який видаляє невикористаний код з бази коду ) служби, якщо нічого не вводить.

Якщо в сервісі неможливо вказати, який модуль повинен її надавати, ви також можете оголосити постачальника послуги в межах модуля:

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

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

4
Найкраще пояснення.
NOP

2
ця відповідь краще, ніж визначення у кутовій док. дуже зрозуміло.
Шамеера Ануранга

2
Дуже добре пояснено, спасибі велике!
Закі Мухаммед

А як бути, коли він порожній, наприклад @Injectable()?
Бен Таліадорос

13

providedIn повідомляє Angular, що кореневий інжектор відповідає за створення примірника вашої служби. Служби, що надаються таким чином, автоматично стають доступними для всієї програми та не потребують їх переліку в жодному модулі.

Класи обслуговування можуть виступати як власні провайдери, тому визначення їх у декораторі @Injectable - це вся необхідна реєстрація.


4

Відповідно до Documentation:

Реєстрація постачальника у метаданих @Injectable () також дозволяє Angular оптимізувати додаток, видаливши службу зі складеного додатка, якщо він не використовується.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.