Как мне разрешить это Angular 7 «Обнаружена циклическая зависимость» - PullRequest
2 голосов
/ 18 марта 2020

В моем проекте Angular 7 мне нужен файл "pages.ts", в который я экспортирую маршруты, которые будет иметь мое приложение. Они импортируются "app-routing.ts" для использования в RouterModule, а также импортируются "pages.service.ts", где я хочу управлять данными этих маршрутов. Теперь в одном из моих компонентов «test-one.component.ts» я хочу использовать этот сервис «pages.service.ts», чтобы я мог получить, например, данные маршрута по его пути или названию. Все работает правильно, но появляется это предупреждение.

ПРЕДУПРЕЖДЕНИЕ в Обнаружена циклическая зависимость: src / app / pages / test-one / test-one.component.ts -> src / app / core / services / pages.service.ts -> src / app / core / constants / pages.ts -> src / app / pages / test-one / test-one.component.ts

" pages.ts "

import { Page } from '../../core/models/page.model';
import { LoginComponent } from '../../pages/login/login.component';
import { SignupComponent } from '../../pages/signup/signup.component';

export const routePages: Page[] = [
    {
        path: '',
        redirectTo: 'login',
        pathMatch: 'full'
    },
    {
        path: 'login',
        component: LoginComponent,
        canActivate: [],
        data: {
            title: 'Login',
            description: '',
            keywords: '',
            icon: 'fingerprint',
            hasBreadcrumb: true
        },
        pathMatch: 'full'
    },
    {
        path: 'sign-up',
        component: SignupComponent,
        canActivate: [],
        data: {
            title: 'Sign up',
            description: '',
            keywords: '',
            hasBreadcrumb: true
        },
        pathMatch: 'full'
    }
];

" app-routing.module.ts "

import { routePages } from './core/constants/pages';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

@NgModule({
  imports: [RouterModule.forRoot(routePages, { scrollPositionRestoration: 'enabled' })],
  exports: [RouterModule]
})
export class AppRoutingModule { }

" pages.service.ts "

import { routePages } from './../constants/pages';
import { Page, PageData } from './../models/page.model';
import { Router } from '@angular/router';
import { Injectable, EventEmitter } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class PagesService {
  pages = routePages;
  private pagesChanged: EventEmitter<Page[]> = new EventEmitter<Page[]>();

  constructor(private location: Location, private router: Router) {
    this.setPagesFullPath();
    console.log(this.pages);
  }
.
.
.

}

"test-one.component.ts"

import { Page, PageData } from './../../core/models/page.model';
import { PagesService } from './../../core/services/pages.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-test-one',
  templateUrl: './test-one.component.html',
  styleUrls: ['./test-one.component.scss']
})
export class TestOneComponent implements OnInit {
  testATwoPage: Page;

  constructor(private pagesService: PagesService) {
  }

  ngOnInit() {
    this.testATwoPage = this.pagesService.getPageByTitle('Test A two');
  }

}

Мне бы хотелось узнать, как можно разрешить эту циклическую зависимость без необходимость обходиться без каких-либо функций.

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 18 марта 2020

Прямого пути нет. Я понимаю ваш вариант использования, хотя и поддерживаю его. Вы не должны иметь такого рода логи c в вашем компоненте. Это должно быть сделано в сервисе. Вы правы в этом. Я не совсем уверен, что лучше всего использовать экспорт Routes. Такое ощущение, что вам лучше использовать свойство Router.config. Который должен содержать всю конфигурацию маршрута:

@Injectable({
  providedIn: 'root'
})
export class PagesService {
  readonly pages: Routes = this.router.config;
  private pagesChanged: EventEmitter<Page[]> = new EventEmitter<Page[]>();

  constructor(private location: Location, private router: Router) {
    this.setPagesFullPath();
    console.log(this.pages);
  }
}

Если это по каким-либо причинам не работает. Чтобы избавиться от циклических зависимостей, можно разбить несколько файлов. Главная проблема - это ваша routePages. Вы можете преобразовать это в два файла. Один из них: pages.ts:

pages.ts

export enum PageRoute {
  Login: 'login',
  SignUp: 'sign-up'
}

export interface PageData {
  title: string;
  description: string;
  keywords: string;
  icon?: string;
  hasBreadcrumb: boolean;
}

export const PageRouteData: Record<PageRoute, PageData> {
  [AppPage.Login]: {
    title: 'Login',
    description: '',
    keywords: '',
    icon: 'fingerprint',
    hasBreadcrumb: true
  },
  [AppPage.SignUp]: {
    title: 'Sign up',
    description: '',
    keywords: '',
    hasBreadcrumb: true
  }
}

И другой файл, который фактически содержит ваши маршруты, которые перевариваются маршрутизатором:

app.routes.ts

export const routePages: Page[] = [
  {
      path: '',
      redirectTo: PageRoute.Login,
      pathMatch: 'full'
  },
  {
      path: PageRoute.Login,
      component: LoginComponent,
      data: PageRouteData[PageRoute.Login]
  },
  {
      path: PageRoute.SignUp,
      component: SignupComponent,
      data: PageRouteData[PageRoute.SignUp]
  }
];

Примечание: pathMatch необходимо, только если у вас есть redirectTo

Это вам не нужно импортировать app.routes в PagesService, и круговая зависимость разрешается

0 голосов
/ 18 марта 2020

Я не знаю, какова цель PageService, но я думаю, что это неправильно. Для доступа к данным маршрутизатора вы должны использовать события Router или ActivatedRoute, а затем делать все, что вам нужно сделать. Например, в этом фрагменте кода я получаю информацию из маршрута для использования в сухарях:

this.router.events
      .pipe(
        filter(event => event instanceof NavigationEnd),
        map(() => {
          return this.getFirstChild(this.route.firstChild);
        })
      )
      .subscribe(child => {
        const title = child.snapshot.data['title'];
        const previous = child.snapshot.data['previous'];
        const parentUrl = child?.snapshot.parent?.url;
        ...
      })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...