typescript 初始化前无法访问'PlanningModule'

tag5nh1u  于 2023-02-14  发布在  TypeScript
关注(0)|答案(3)|浏览(171)

我正在使用来自themeforest的apex主题。我正在尝试访问该页面:/planning但是,控制台显示错误:

core.js:6014 ERROR Error: Uncaught (in promise): ReferenceError: Cannot access 'PlanningModule' before initialization
ReferenceError: Cannot access 'PlanningModule' before initialization
    at Module.PlanningModule (planning.component.ts:12)
    at planning-layout.routes.ts:6

我没有组件的双重初始化,也没有模块的双重初始化,只有app.module里面的服务初始化,为什么会出现这个错误,怎么解决?
App-routing.module.ts:

{
    path: 'planning',
    component: FullLayoutComponent,
    children: Planning_ROUTES,
    canActivate: [AuthGuard],
},

Planning.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {PlanningComponent} from './planning.component';
import {FormsModule} from '@angular/forms';
import {DragulaModule} from 'ng2-dragula';
import {Ng2SmartTableModule} from 'ng2-smart-table';
import {NgSelectModule} from '@ng-select/ng-select';
import {PlanningRoutingModule} from './planning-routing.module';

@NgModule({
  declarations: [
    PlanningComponent
  ],
  imports: [
    CommonModule,
    FormsModule,
    DragulaModule.forRoot(),
    Ng2SmartTableModule,
    NgSelectModule,
    PlanningRoutingModule
  ]
})
export class PlanningModule { }

Planning-routing.module.ts:

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

import {PlanningComponent} from './planning.component';

const routes: Routes = [
  {
    path: '',
    component: PlanningComponent,
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class PlanningRoutingModule {
  constructor() {
    console.log('hier komt die(niet)');
  }
}

PlanningComponent.ts:

import {Component, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import {PlanningService} from './planning.service';

@Component({
  selector: 'app-planning',
  templateUrl: './planning.component.html',
  styleUrls: ['./planning.component.scss'],
})
export class PlanningComponent implements OnInit {

  constructor(private router: Router,
    private planningService: PlanningService) {}

  ngOnInit(): void {}
}

Planning-routes.ts:

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

export const Planning_ROUTES: Routes = [
  {
    path: '',
    loadChildren: () => import('../../pages/planning/index/planning.module').then(m => m.PlanningModule)
  },
];
jw5wzhpr

jw5wzhpr1#

当你在一个或多个Angular 模块之间有循环依赖时就会发生这种情况。我发现即使依赖是间接的,比如服务导入,也会发生这种情况。我假设这与初始化顺序有关。
例如-
此组件依赖于另一个模块子目录中定义的服务-

// declared in A_Module
export class A_Component implements OnInit {
//...
  constructor(
    private service: B_Service) {} // <-- dependency on B_Module??

}
// B_Module
@NgModule({
  imports: [
    CommonModule,
    A_Module // <-- dependency 
  ],
  exports: [],
  declarations: [...],
  providers: []
})
export class B_Module { }

// In B_Module sub-directory
@Injectable({providedIn: 'root'})
export class B_Service {}

为了解决这个问题,我在A_Component中使用了一个Input()绑定。一个选项可能是将服务移动到共享模块文件夹下。

agxfikkp

agxfikkp2#

我仍然不完全理解为什么我自己会得到这个错误,但是我能够用两种解决方案之一来绕过它。
首先--我不希望这是对我的代码的全面概述--这里有一个概述:
1.我正在生成一个使用自定义注入器的动态组件树。
1.这个定制注入器为树中的每个级别注入了一个服务ConfigService

  1. ConfigService对于树中的每个级别都是唯一的。
    1.还有其他服务使用该组件提供的ConfigService
    1.我想在子节点中访问祖先的ConfigService,所以我在SectionComponent中执行了此操作
{ provide: SECTION_CONFIG, useExisting: ConfigService }

然后在child中,我将SECTION_CONFIG作为parentSectionConfig: ConfigService注入。
不幸的是,这是当我得到的错误,这是纯粹的ES引用错误,没有Angular 信息。它 * 似乎 * 发生,因为我正在使用useExisting,所以在代码路径中的东西是试图访问的东西之前,它的创建。
当Angular创建一个组件时,它必须弄清楚创建所有依赖项的正确顺序,似乎我已经设法绊倒了它。

溶液1:

我刚刚创建了一种存根服务来添加额外的间接性:

providers: [
    ConfigServiceStub,  // create the stub
    { provide: SECTION_CONFIG, useExisting: ConfigServiceStub }
]

或者简单地说(哪个更好):

providers: [
    { provide: SECTION_CONFIG, useClass: ConfigServiceStub }
]

ConfigServiceStub是一个服务,它只注入ConfigService一些私有方法来从它返回重要数据。
这是有效的。唯一的区别是额外的间接层,Angular编译器现在可以使用。注意,我实际上仍然使用useExisting,但它现在标记到一个新的服务,能够捕获正确的依赖关系。
如果你读了所有这些,然后说"嗯,这没有意义吗?"你可能是对的,还有很多代码我没有包括在内。但无论是什么,我都能够修复它,而不需要真正重新组织任何东西。它看起来不像一个循环引用,因为你不能通过添加另一个间接层来修复循环引用。

溶液2

基本相同的解决方案,但使用工厂:

{ provide: SECTION_CONFIG, useFactory: SectionConfigFactory, deps: [ ConfigService ] }

 export const SectionConfigFactory = (dep1: ConfigService) => dep1;

这也可以工作,而且也不是重新组织组件或. ts文件图中的任何东西-只是为了它而添加了一个间接层。
在我看来,整个情况听起来像是一个bug,不管是什么算法决定了要创建的东西的顺序,但幸运的是,这个变通方案起作用了,或者可能是不可能的,因为自定义注入器注入了我的SectionComponent在编译时不可能知道的服务。

s5a0g9ez

s5a0g9ez3#

我遇到了同样的错误。我的模块正在注入一个服务,它位于一个共享模块文件夹中,如果我删除了这个服务,错误就会消失。我在那个服务中使用了npm assert包。当我删除它时,问题就解决了。不幸的是,我不知道为什么/如何assert包会导致问题。

相关问题