Ionic 6/Capacitor模态页使用自定义组件报错的原因与解决
封装了可复用的FabButton组件,在普通页面中能正常工作,但在模态页使用时抛出以下错误:
core.mjs:7626 ERROR Error: Uncaught (in promise): Error: Type FabbuttonComponent is part of the declarations of 2 modules: ListmodalPageModule and RecipesPageModule! Please consider moving FabbuttonComponent to a higher module that imports ListmodalPageModule and RecipesPageModule. You can also create a new NgModule that exports and includes FabbuttonComponent then import that NgModule in ListmodalPageModule and RecipesPageModule.
原因分析
Angular的核心规则:一个组件只能被一个NgModule声明。你目前把FabbuttonComponent同时添加到了RecipesPageModule(普通页面的模块)和ListModalPageModule(模态页模块)的declarations数组中,这违反了Angular的模块隔离机制,因此触发报错。普通页面之前能正常工作,是因为当时组件只在单个模块中声明,没有冲突;添加模态页模块的声明后,就出现了重复声明的问题。
解决方案
创建一个共享组件模块,将FabbuttonComponent放入该模块并导出,之后所有需要使用该组件的页面模块,只需要导入这个共享模块即可,无需重复声明组件。
步骤1:创建共享组件模块
新建components.module.ts文件,内容如下:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IonicModule } from '@ionic/angular'; import { FabbuttonComponent } from './fabbutton/fabbutton.component'; @NgModule({ declarations: [FabbuttonComponent], // 仅在此声明组件 imports: [ CommonModule, IonicModule // 导入Ionic模块以支持ion-fab等组件 ], exports: [FabbuttonComponent] // 导出组件,让其他模块可以使用 }) export class ComponentsModule {}
步骤2:修改原有页面模块
修改ListModalPageModule
移除declarations中的FabbuttonComponent,改为导入ComponentsModule:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { IonicModule } from '@ionic/angular'; import { ListModalPageRoutingModule } from './listmodal-routing.module'; import { ListModalPage } from './listmodal.page'; import { ComponentsModule } from 'src/app/components/components.module'; // 导入共享模块 @NgModule({ imports: [ CommonModule, FormsModule, IonicModule, ListModalPageRoutingModule, ComponentsModule // 添加共享模块到imports ], declarations: [ListModalPage] // 移除FabbuttonComponent }) export class ListModalPageModule {}
修改RecipesPageModule
同样移除declarations中的FabbuttonComponent,导入ComponentsModule:
// 其他导入保持不变 import { ComponentsModule } from 'src/app/components/components.module'; @NgModule({ imports: [ // 原有导入项 ComponentsModule // 添加共享模块 ], declarations: [RecipesPage] // 移除FabbuttonComponent }) export class RecipesPageModule {}
步骤3:验证使用
现在无论是普通页面还是模态页,都可以正常使用<app-fabbutton (onClick)="scrollToTop()"></app-fabbutton>,不会再出现重复声明的错误。
内容的提问来源于stack exchange,提问作者Fearcoder

