【发布时间】: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