Angular 6 - создание службы с областью видимости (не корневого) модуля

Насколько мне известно, до angular 6 все поставщики @Ngmodule были зарегистрированы на корневом инжекторе и обслуживались в основном пакете, даже если их использовали только ленивые загруженные модули.

Единственным исключением из этого правила было то, что мы хотели создавать не одноэлементные службы на уровне компонентов.

Я хочу создать одноэлементную службу, которая будет видна только определенному модулю (а не корневому модулю), и в результате этого не будет обслуживаться в основном загруженном пакете.

Мы видели, что в angular 6 модулю больше не нужно будет ссылаться на службу через «провайдеров», а теперь служба будет ссылаться на модуль.

Это можно сделать с помощью аннотации @Injectable и атрибута provideIn.

Я не нашел хорошего и ясного примера того, как я могу добавить имя модуля, которое не является root, что-то вроде этого:

@Injectable({ provideIn: <MyLocalModule>})
export class SimpleServiceForLocalUseOnly { […] }

Импорт модуля LazyLoaded и запись его как «MyLocalModule» в приведенном выше фрагменте вызывает ПРЕДУПРЕЖДЕНИЕ о круговой зависимости. Я могу решить эту проблему, переместив службу в другой модуль, но тогда я теряю свою первоначальную цель.

Список искомых ссылок:

https://blog.angular.io/version-6-of-angular-now-available-cc56b0efa7a4

https://jaxenter.com/new-angular6-143995.html

https://www.ngdevelop.tech/angular-6-features/

https://blog.ninja-squad.com/2018/05/04/what-is-new-angular-6/

http://ankitsharmablogs.com/getting-started-with-angular-6-0/

https://thewikihow.com/video_Xr5l7lT--YU

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
4
0
3 266
3

Ответы 3

Кажется, есть некоторые проблемы с круговой зависимостью, если мы будем следовать этой настройке в соответствии с официальные документы:

import { Injectable } from '@angular/core';
import { HeroModule } from './hero.module';
import { HEROES }     from './mock-heroes';

@Injectable({
  // we declare that this service should be created
  // by any injector that includes HeroModule.

  providedIn: HeroModule,
})
export class HeroService {
  getHeroes() { return HEROES; }
}

Вы можете игнорировать предупреждения, которые генерирует компилятор из-за циклической зависимости между модулем, службой и компонентом. Или вернитесь к предыдущим методам, используемым в Angular 5.

Зарегистрируйте сервис как провайдера в модуле с отложенной загрузкой, обратите внимание, что вы не должны импортировать модули с отложенной загрузкой в ​​модуль корневого приложения:

@NgModule({
  imports: [
    RouterModule.forChild([{ path: '', component: LazyComponent }]),
  ],
  declarations: [
    LazyComponent
  ],
  providers: [YourServiceHere]
})
export class LazyLoadedModule { }

Когда я это делаю, я получаю: ПРЕДУПРЕЖДЕНИЕ в обнаружении круговой зависимости: HeroService -> HeroModule -> HeroComponent -> HeroService

RtmY 09.05.2018 12:06

это может быть проблема с самой библиотекой Angular, в основном потому, что для этой настройки требуется циклический импорт службы, модуля и компонента. Если это просто ПРЕДУПРЕЖДЕНИЕ, и ваше приложение работает, я думаю, что его можно игнорировать. Или вы могли бы просто не использовать способ настройки сервисов на уровне модуля. Просто настройте службу в массиве поставщиков в вашем ленивом загружаемом модуле.

Joshua Chan 09.05.2018 12:28

Но моей первоначальной целью было не включать эту услугу в основной пакет, добавление ее в массив поставщиков модулей приведет к такому результату.

RtmY 09.05.2018 12:47

вы ленивы загружаете свой модуль? Насколько я понимаю, службы, зарегистрированные в модулях с ленивой загрузкой, также загружаются лениво.

Joshua Chan 09.05.2018 12:51

Да, этот модуль загружается лениво, и службы, зарегистрированные в «провайдерах» модуля, добавляются в корневой инжектор и не загружаются лениво (проверьте, что вы основной пакет, и посмотрите). Насколько я понимаю, в angular 6 он был изменен (во второй ссылке есть хорошая обложка).

RtmY 09.05.2018 12:57

Я понимаю. Возможно, нам придется игнорировать предупреждения, пока новая версия не решит эту проблему. Извини, что не смог тебе с этим помочь.

Joshua Chan 09.05.2018 13:02

Здравствуйте, я сам убедился, что сервисы, зарегистрированные в модулях с отложенной загрузкой, не входят в основной пакет. Добавлю настройку в ответ.

Joshua Chan 09.05.2018 14:10

Вы с угловой 6? Значит, идет из коробки?

RtmY 09.05.2018 14:18

Чтобы предоставить услугу в конкретном модуле с использованием нового синтаксиса, вам просто нужно сделать что-то вроде этого:

import { Injectable } from "@angular/core";
import { YourModule } from "path/to/your.module";

@Injectable({
    providedIn: YourModule
})
export class SomeModuleScopedService {}

ссылка: https://angular.io/guide/providers#providedin-and-ngmodules

Он дает предупреждение о циклической зависимости, как указано в вопросе.

Nuryagdy Mustapayev 03.03.2021 12:24

Я заставил это работать, создав промежуточный модуль, который содержит только службу.

import { Injectable } from '@angular/core';
import { HeroServiceModule } from './hero.service.module';

@Injectable({
  providedIn: HeroServiceModule,
})
export class HeroService {
}

В этом модуле много не нужно:

@NgModule({
  imports: [ CommonModule ]
})
export class HeroServiceModule {}

Затем ваш обычный модуль импортирует служебный модуль:

@NgModule({
...
  imports: [
...
     HeroServiceModule
  ]
})
export class HeroModule {}

Затем вы можете отложить загрузку HeroModule как обычно. Это устраняет все циклические зависимости.

Другие вопросы по теме