Angular class 使用服务创建循环依赖

Angular class that uses service creates circular dependency

我有一个菜单服务,它使用菜单 classes 保存菜单结构。菜单 classes 使用 menuItem classes.

该服务执行一些 http 请求以获取数据。从这个数据菜单中创建 classes。下面的代码被大大简化了。

import { Injectable, OnInit } from '@angular/core';
import { RequestOptions } from '@angular/http';
import { HttpClient, HttpClientModule, HttpHeaders } from '@angular/common/http';
import { Observable } from "rxjs/Observable"

import { Menu } from "../classes/menu";
import { MenuItem } from "../classes/menuItem";
import { menusResponseInterface } from "../interfaces/menusResponse";
import { DataService } from './data.service';
import { ConfigService } from './config.service';

@Injectable()
export class MenusService {
  private menus;
  private getMenuesObservers$;
  private getMenuesObserver;
  private getMenusStateObservers$;
  private getMenusStateObserver;
  private urls;

  constructor(
    private http: HttpClient,
    private data: DataService,
    private config: ConfigService
  ) {
    this.getMenuesObservers$ = [];
    this.menus = [];
    this.urls = {};
    this.init();
  }

  init(){
    this.getMenuesObserver = new Observable(observer => {
      this.getMenuesObservers$.push(observer);
    });
    this.getMenusStateObserver = new Observable(observer => {
      this.getMenusStateObservers$ = observer;
    });

    this.http.get(`${this.config.baseURL}/api/getMenues`).subscribe((response:menusResponseInterface) => {
      var index;

      for( index in response.menus){
        this.menus[index] = new Menu(response.menus[index]);
        this.menus[index].setMenuItems(response.pages[index]);
      }

      for( var i = 0; i< this.getMenuesObservers$.length; i++){
        this.getMenuesObservers$[i].next(this.menus);
      }
    });
  }

  public getMenues(){
    return this.getMenuesObserver;
  }


  public function getMenuItemByUrl:MenuItem(url:string){

  }

}

菜单 Class 创建菜单项的树结构。

import { MenuItem } from "./menuItem";
export class Menu {
    public setMenuItems(menuItems){
        // loop data and create treeStructure of MenuItems
        menuItem = new MenuItem(menuItems);

        .
        .
        .

        menuItem.children.push(childMenuItem);
    }    
}

MenuItem class 包含有关 parent、孩子、姓名和 url 的数据。 url 是通过询问所有 parent 的名字加上自己的名字来创建的。我想再次将 MenuService 注入 MenuItem class,这样我就可以将所有 url 发送给它。我想在 MenuService 中包含所有 URL,以便我可以将它与路由器匹配 url,

import { MenusService } from '../services/menus.service';
import {ReflectiveInjector} from '@angular/core';

export class MenuItem {
   public id:number;
   public name:string;
   private url:string;
   .
   .
   .

   public children:Array<MenuItem>;
   public parent:MenuItem;

   private menuService:MenusService

   constructor(
       data
   ){
       let injector = ReflectiveInjector.resolveAndCreate([MenusService]);
       this.menuService = injector.get(MenusService);
   }
   
   .
   .
   .

   public getUrl(){
       if(typeof(this.url) == "undefined"){
           if(typeof(this.parent) == "undefined" || this.parent.id == 0){
               this.url = encodeURI(this.name.replace(new RegExp(/ / , 'g'), '-'));
           }
           else{
               this.url = this.parent.getUrl()+'/'+encodeURI(this.name.replace(new RegExp(/ / , 'g'), '-'));
           }
           this.menuService.registerURL(this.url, this);
       }
       return this.url;
    }
}

如果不产生循环依赖,这会很好用。 MenuService 使用 Menu,Menu 使用 MenuItem,MenuItem 使用 MenuService。将 MenuService 注入 MenuItem 后 Class 我收到循环依赖警告并且应用程序中断。

有没有 Angular 的方法来解决这个问题而没有这个循环依赖问题?

这里有一些详细说明了我关于使用 Subject 与服务通信的评论:

// MenuItem.ts
static registerUrl:Subject<MenuItem> = new Subject();
// instead of service.registerUrl():
MenuItem.registerUrl.next(this)

// service onInit
MenuItem.registerUrl.subscribe(item => {
    // do stuff with item.url
});

瞧,MenuItem 不需要导入服务。