Angular 6+: предоставляется в некорневом модуле, вызывает циклическую зависимость - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь предоставить службу разрешения с помощью нового атрибута providedIn.

Это средство преобразования переводов, которое я использую в защищенном модуле:

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

import { Observable , pipe } from 'rxjs';
import {map} from "rxjs/operators";

//This is causing: "WARNING in Circular dependency detected:"
import {ProtectedModule} from "../../../protected/protected.module";

import { HttpHandlerService } from '../../http/http-handler.service';

@Injectable({
  providedIn: ProtectedModule //Over here (I need the import for this line)
})
export class TranslationsResolverService {
  constructor(private _httpHandlerService : HttpHandlerService) { }
    resolve(): any {
      //Do Something...
    }
}

Я объявил службу распознавания переводов в защищенном модуле маршрутизации:

import { NgModule }           from '@angular/core';
import {RouterModule, Routes} from '@angular/router';

import {AuthGuard} from "../core/resolvers/auth/auth.guard";
import {TranslationsResolverService} from "./../core/resolvers/translations/translations-resolver.service";

const routes: Routes = [
  {
    path : 'app' ,
    component: ProtectedComponent,
    resolve : {
      translations : TranslationsResolverService // <---- Over here - i can't remove that of course
    },
    canActivate: [AuthGuard],
    ]
  }
];


@NgModule({
  imports : [RouterModule.forChild(routes)],
  exports : [RouterModule]
})
export class ProtectedRoutingModule { }

Из-за того, что я импортирую (импорт машинописного текста) protected.module в translations-resolver.service.ts , чтобы использовать его в атрибуте providedIn , я получаю ПРЕДУПРЕЖДЕНИЕ при обнаружении циклической зависимости:

path/to/translations-resolver.service.ts -> 

protected/protected.module.ts ->

protected/protected-routing.module.ts -> 

path to translations-resolver.service.ts

2-й путь (protected / protected.module.ts) добавлен из-за атрибута providedIn.

Я могу исправить это, просто указав translationsResolver как NgModule provider (в массиве провайдеров), но я предпочитаю, чтобы он был injectable провайдером.

Есть предложения по решению этой проблемы?

Ответы [ 4 ]

0 голосов
/ 25 мая 2019

Я думаю, что Angular немного напутал в синтаксисе providedIn. Кажется, это смутило многих людей. Например. посмотрите эти две темы GitHub:

Синтаксис providedIn имеет 2 основных преимущества :

  1. Поддерживается расшатывание неиспользуемых сервисов
  2. providedIn: 'root' гарантирует, что вы получите только один экземпляр услуги

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

Проблемы с синтаксисом providedIn:

  1. providedIn: 'root' разрывает связь между службой и модулем, в котором она «живет» (или «с») - потому что служба не знает о модуле, а модуль не знает о службе. Это означает, что сервис больше не «принадлежит» этому модулю и будет просто связан с тем, что на него ссылается. Это, в свою очередь, означает, что теперь служба должна потребитель убедиться, что инъекционные зависимости службы (если они есть) доступны до ее использования, что вводит в заблуждение и довольно нелогично.
  2. Задача круговой ссылки, описанная выше. Фактически невозможно - с помощью этого синтаксиса - сохранить связь между службой и ее модулем, , если служба фактически используется какими-либо компонентами в том же модуле .

Это противоречит официальному руководству Angular, но мой совет: Не используйте providedIn, если только вы не пишете стороннюю библиотеку, которая требует встряхивания дерева - используйте старую (не устарел) providers вместо этого синтаксис в модуле, то есть:

@NgModule({ providers: [MyService], })

0 голосов
/ 29 июня 2018

Я столкнулся с той же проблемой. Оказывается, решение «не делай этого», как объяснил в этой теме один из парней из Angular: https://github.com/angular/angular-cli/issues/10170#issuecomment-380673276

Это сводится к тому, что сервисам легче встряхнуть дерево, когда они предоставляются корневым модулем, насколько я понимаю.

Я так же разочарован, как и вы.

0 голосов
/ 23 июля 2018

Это не проблема угловых зависимостей.

Циклическая ссылка генерируется компилятором TypeScript, когда он пытается разрешить циклический import .

Первое решение

Создайте новый модуль с именем ProtectedResolversModule, используйте providedIn: ProtectedResolversModule и переместите преобразователи туда.

Теперь вы можете импортировать этот модуль в ProtectedModule, и при загрузке ProtectedRoutingModule.

вы не получите циклическую ошибку зависимости.

Второе решение

Используйте массив providers из ProtectedModule.

0 голосов
/ 28 июня 2018

Проверка forwardRef () функция от угла / сердечника. Это позволяет ссылаться на ссылки, которые еще не определены.

import {MyService} from './service';

constructor(@Inject(forwardRef(() => MyService)) public myService: MyService) {
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...