懒加载 BrowserModule 已经被加载过了。

123
我正在尝试实现延迟加载,但是遇到以下错误:

错误:未捕获的(在承诺中):错误:BrowserModule已经被加载。如果您需要从惰性加载的模块中访问常见指令(如NgIf和NgFor),请导入CommonModule。

我需要帮助解决这个问题。 以下是我的模块:
  1. 共享模块
@NgModule({

  declarations: [TimePipe],
  providers: [
    EmsEmployeeService,
    EmsDesignationService,
    EmsOrganizationService,
    EmsAuthService,
    AmsEmployeeService,
    AmsShiftService,
    ValidatorService,
    AmsLeaveService,
    AmsAttendanceService,
    AmsDeviceService,
    AmsOrganizationService,
    AmsAlertService,
    AmsHolidayService,
    AutoCompleteService,
    AmsTimelogsService,
    LocalStorageService
  ],
  imports: [
    HttpModule,
    ToastyModule.forRoot(),
    AgmCoreModule.forRoot({
      apiKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
    }),
  ],
  exports: [
    FormsModule,
    HttpModule,
    BrowserAnimationsModule,
    RouterModule,
    MaterialModule,
    MdDatepickerModule,
    MdNativeDateModule,
    ToastyModule,
    FileUploadModule,
    NgxPaginationModule,
    NguiAutoCompleteModule,
    AgmCoreModule,
    TimePipe
  ]
})
export class SharedModule { }

2.SettingModule

 @NgModule({
  imports: [
    CommonModule,
    SharedModule,
    SettingsRoutingModule
  ],
  declarations: [
    SettingsComponent,
    ShiftsComponent,
    DevicesComponent,
    AlertsComponent,
    HolidaysComponent,
    AlterTypesComponent,
    AlterEditComponent,
    ShiftTypeNewComponent,
    DeviceLogsComponent,
    ChannelTypesComponent,
    ChannelTypeEditComponent
  ], exports: [
    SettingsComponent,
    ShiftsComponent,
    DevicesComponent,
    AlertsComponent,
    HolidaysComponent,
    AlterTypesComponent,
    AlterEditComponent,
    ShiftTypeNewComponent,
    DeviceLogsComponent,
    ChannelTypesComponent,
    ChannelTypeEditComponent,
  ]
})
export class SettingsModule { }
3.SettingRoutingModule
const settings_routes: Routes = [
  { path: '', redirectTo: 'shifts', pathMatch: 'full' },
  { path: 'shifts', component: ShiftsComponent },
  { path: 'shifts/new', component: ShiftTypeNewComponent },
  { path: 'shifts/edit/:id', component: ShiftTypeNewComponent },
  { path: 'devices', component: DevicesComponent },
  { path: 'deviceLogs', component: DeviceLogsComponent },
  { path: 'holidays', component: HolidaysComponent },
  { path: 'alerts', component: AlertsComponent },
  { path: 'alerts/types', component: AlterTypesComponent },
  { path: 'alerts/:id', component: AlterEditComponent },
  { path: 'channelTypes', component: ChannelTypesComponent },
  { path: 'channelTypes/:id', component: ChannelTypeEditComponent }
];


const routes: Routes = [
  { path: '', component: SettingsComponent, children: settings_routes }
];



@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class SettingsRoutingModule { }
  1. 应用程序路由模块
const attdendance_routes: Routes = [
  { path: '', redirectTo: 'daily', pathMatch: 'full' },
  { path: 'monthly', component: MonthlyComponent },
  { path: 'daily', component: DailyComponent },

  { path: 'daily/:empId', component: AttendanceDetailsComponent },
  { path: 'details/:empId', component: AttendanceDetailsComponent },
  { path: 'monthly/:empId', component: AttendanceDetailsComponent },
  { path: 'leaves/:empId', component: AttendanceDetailsComponent },

  { path: 'details/:empId/apply-leave', component: ApplyLeaveComponent },
  { path: 'daily/:empId/apply-leave', component: ApplyLeaveComponent },
  { path: 'daily/:empId/attendance-logs/:ofDate', component: AttendanceLogsComponent },
  { path: 'monthly/:empId/apply-leave', component: ApplyLeaveComponent },
  { path: 'leaves/:empId/apply-leave', component: ApplyLeaveComponent },
  { path: 'leaves/new/apply', component: ApplyLeaveComponent },

  { path: 'leaves', component: LeavesComponent },
  { path: 'leave-balances', component: LeaveBalancesComponent },
  { path: 'leave-balances/:empId', component: AttendanceDetailsComponent },
  { path: 'manage-leaves', component: ManageLeavesComponent },

];



const emp_routes: Routes = [
  { path: '', redirectTo: 'list', pathMatch: 'full' },
  { path: 'list', component: EmployeeListComponent },
  { path: 'list/:id', component: EmpEditComponent },
  { path: 'designations', component: DesignationsComponent }
];



const page_routes: Routes = [
  { path: '', redirectTo: 'attendances', pathMatch: 'full' },
  { path: 'employees', component: EmployeesComponent, children: emp_routes },
  { path: 'attendances', component: AttendancesComponent, children: attdendance_routes },

  { path: 'settings', loadChildren: './pages/settings/settings.module#SettingsModule' },
];

// main routes
const routes: Routes = [
  { path: '', redirectTo: 'pages', pathMatch: 'full' },
  { path: 'login', component: LoginComponent, canActivate: [LoginGuard] },
  { path: 'pages', component: PagesComponent, canActivate: [UserGuard], children: page_routes },
  { path: 'loginViaOrg', component: OrgLoginComponent },
  { path: 'download', component: AppDownloadComponent },
  { path: '**', redirectTo: 'pages' },
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { useHash: true })],
  exports: [RouterModule]
})
export class AppRoutingModule { }

5.AppModule

@NgModule({

  declarations: [
    AppComponent,
    PagesComponent,
    LoginComponent,
    EmployeesComponent,
    OrgLoginComponent,
    EmployeeListComponent,
    EmpEditComponent,
    DayEventDialogComponent,
    AttendancesComponent,
    MonthlyComponent,
    AttendanceDetailsComponent,
    DailyComponent,
    DeviceDialogComponent,
    LeaveActionDialogComponent,
    LeavesComponent,
    LeaveBalancesComponent,
    ManageLeavesComponent,
    ApplyLeaveComponent,
    ConfirmDialogComponent,
    ResetPasswordDialogComponent,
    AppDownloadComponent,
    DesignationsComponent,
    AttendanceLogsComponent,
  ],

  entryComponents: [
    DayEventDialogComponent,
    DeviceDialogComponent,
    LeaveActionDialogComponent,
    ConfirmDialogComponent,
    ResetPasswordDialogComponent
  ],

  imports: [
    BrowserModule,
    // CommonModule,
    SharedModule,
    AppRoutingModule,
    // feature modules
    // SettingsModule
  ],

  providers: [
    LoginGuard, UserGuard,
  ],

  bootstrap: [AppComponent]
})
export class AppModule { }

你是在 index.html 的初始加载时还是在导航到 /settings 时遇到这个错误的? - Günter Zöchbauer
在导航到“/settings”时,请@GünterZöchbauer。 - Er Sushil
你确定除了 AppModule 之外的所有涉及模块都没有导入 BrowserModule 吗? - Günter Zöchbauer
4
我找到了解决方法,我在子模块中导入了BrowserAnimationsModule。 - Er Sushil
1
很高兴听到你能够让它工作:) 感谢您的反馈! - Günter Zöchbauer
显示剩余4条评论
14个回答

307

请在您的根模块中只导入一次BrowserModule, BrowserAnimationsModule, HttpModuleHttpClientModule,最好不要改变原有结构。


38
没问题!它有效!只需要稍微补充一下:如果您同时使用BrowserAnimationsModuleBrowserModule,它们应该在同一个模块中引入。 - Alvaro
4
对于那些使用NoopAnimationsModule的人,同样适用这个规则。我不得不移动那个模块。 - harmonickey
1
这太对了。我试图使用Angular CLI 9生成一个惰性模块,但输出错误是这个不具描述性的“无法读取未定义属性”的错误。这个答案让我免于烧毁房间。我欠你Jota。 - bwinchester
1
我不得不在最后导入AppRoutingModule,这解决了我的错误。但是我无法弄清楚原因。 - Amit Chigadani
@Alvaro,你的信息和Jota的答案应该被写入Angular-Docs中!谢谢你们。 - Ilker Cat
显示剩余4条评论

12

我遇到了同样的问题,Jota.Toledo 给出了正确的答案,我只想扩展一下:请检查共享模块中导入与

@angular/platform-browser/animations

相关的任何模块,并将这些模块移动到 app.module.ts 中。


我在 app.module.ts 中没有导入 NoopAnimationsModule:)立即解决了我的问题。 - Crushnik

11

我也遇到了同样的错误,经过一番努力后,最终成功解决。

只需在应用程序模块中导入这些模块(仅导入一次):

BrowserModule、 BrowserAnimationsModule、 LazyLoadImageModule (如果使用)、 CarouselModule (如果使用)、 InfiniteScrollModule (如果使用)、 HttpModule (如果使用)


6
这对我有用,但是现在我该如何使用来自AppModule之外的CarouselModule和其他模块? - Braelyn B
你可以将其放置在ts模块文件的“imports”部分,以便那些应该具有访问权限的模块可以使用它 @BraelynB - Collin

10

如果您在某个child.app module.ts中导入了BrowseModule,可能会出现此错误。请确保在除app.module外的所有模块中都导入CommonModule,因为它包含浏览器模块。


你可以从 '@angular/common' 导入 CommonModule。 - Fatema Saifee
仍然出现相同的错误。您可以检查一下,我只在AppModule中导入了BrowseModule。 - Er Sushil
是的,我也是,只在应用程序模块中导入。 - Phil

10

在我的情况下,我有一个共享模块,其中导入了BrowserAnimationModule。我正在根模块中导入共享模块。为解决此错误,请从所有模块中删除BrowserAnimationModule的所有导入,并将其添加到根模块中。

imports: [
    AppRoutingModule,
    SharedModule,
    BrowserAnimationsModule
  ],

4

我必须将 BrowserAnimationsModule 从任何子组件的 imports 中移除


1
如果您正在使用多个模块,请在应用程序模块或某些自定义模块中仅使用一次Browser模块,并在自定义模块中从@angular/common导入CommonModule
我曾经遇到过同样的错误,我试图在多个组件/模块中重复使用组件、指令和管道。相反,我将所有可重用组件导入了一个核心模块,并在多个组件/模块中导入了该核心模块。

1

您需要检查应用程序的其他部分是否进行了 BrowserModule 的调用或导入。有些库使用 BrowserModule,这样做会破坏 BrowserModule。


1
在同一个问题上,我也卡了两天,但最终我解决了它!让我分享我的经验,我创建了一个自定义的外部库,目的是用于“常见组件”。我将其部署到了“Azure DevOps Artifacts”上。当我将其安装到我的项目中时,它按预期正常工作。现在,当我尝试在“app-routing-module.ts”中导入一些模块,如“loadChildern”时,我遇到了相同的错误。
错误信息如下: ERROR Error: Uncaught (in promise): Error: BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.
我的项目配置没问题,我犯了一个小错误,那就是我在我的外部库中同时导入了“BrowserModule”和“CommonModule”,所以我只需将“BrowserModule”从中删除即可,这样就可以正常工作,没有任何问题或错误。
我学到了什么:

BrowserModule 是一个根模块,在整个项目中我们只需要在 AppModule 中导入一次,然后可以在其他模块中使用 CommonModule。不能同时使用模块 BrowserModuleCommonModule

这是我从这个经验中学到的,如果我理解错了,请告诉我正确的信息!


1
@First Import BrowerModule and in imports also first include BrowserModule import:[BrowerModule ] 

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

如果我们在除了应用程序模块之外的任何模块中声明BrowserModule,就会出现这个错误。在应用程序模块中,如果我们导入10个模块或插件,首先我们必须在顶部导入BrowserModule并在装饰器中声明(import:[BrowserModule ])

如果我们在除了应用程序模块之外的任何模块中声明BrowserModule(重复),则会出现此错误。在应用程序模块中,如果我们导入10个模块或插件,则首先必须在顶部导入BrowserModule并在装饰器中声明(import:[BrowserModule])。 - Brahmmeswara Rao Palepu
1
我已经编辑了你的答案并加上了解释。请尽可能记得编辑你的问题和答案,而不仅仅是评论 :) - Federico Grandi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接