【问题标题】:Angular class that uses service creates circular dependency使用服务的 Angular 类创建循环依赖
【发布时间】:2020-08-31 23:22:25
【问题描述】:

我有一个菜单服务,它通过使用菜单类来保存菜单结构。菜单类使用 menuItem 类。

服务执行一些 http 请求来获取数据。从此数据创建菜单类。下面的代码被大大简化了。

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){

  }

}

Menu 类创建 MenuItems 的树结构。

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 类包含有关父级、子级、名称和 url 的数据。该 url 是通过询问所有父母那里的名字加上自己的名字来创建的。我想再次将 MenuService 注入到 MenuItem 类中,这样我就可以将所有 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 使用使用 MenuService 的 MenuItem 的 Menu。将 MenuService 注入 MenuItem 类后,我收到循环依赖警告并且应用程序中断。

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

【问题讨论】:

  • 不要在构造函数中解析依赖,而是在真正需要的时候?
  • 参见 getURL 函数。当第一次调用 getUrl 时,它会生成并发送到 MenuService。
  • 如果你将this.menuService = injector.get(MenusService);从构造函数移动到getUrl
  • 同样的问题。 CLI 给出循环依赖警告。我可以编译但应用程序中断,因为在 MenuService 中找不到 HttpClient 的提供程序。
  • 如果你没有在MenuService构造函数中调用init,但是稍后呢?不看http调用在哪里有点难说

标签: angular circular-dependency


【解决方案1】:

以下是我对使用 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 不需要导入服务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多