Angular组件选择器未识别:跨模块组件引用报错咨询
这个问题本质是Angular的组件作用域规则导致的:组件默认只能在声明它的模块内部使用,其他模块想要访问,必须通过正确的模块导出和导入流程来实现。
先分析你的场景
你在AppModule里声明了ConfirmAlertComponent,GraphicsComponent和它同属一个模块,所以直接用选择器没问题;但MyArtComponent属于MyArtModule,这个模块没有任何途径能访问到ConfirmAlertComponent,自然会抛出“未知元素”的错误。同样的,你的One/Two模块例子里,OneComponent所在的OneModule没导入TwoModule(且TwoModule没导出TwoComponent),所以也用不了<app-two>。
推荐解决方案:使用共享模块(SharedModule)
这是Angular项目中跨模块共享组件最规范的做法,步骤如下:
创建SharedModule
新建一个共享模块,把需要跨模块使用的组件(比如ConfirmAlertComponent、TwoComponent这类)声明并导出:@NgModule({ declarations: [ConfirmAlertComponent], exports: [ConfirmAlertComponent], // 导出才能让其他模块使用 imports: [CommonModule] }) export class SharedModule { }在需要的模块中导入SharedModule
- 修改
AppModule:移除ConfirmAlertComponent的声明,换成导入SharedModule@NgModule({ declarations: [GraphicsComponent], imports: [BrowserModule, MyArtModule, SharedModule], // ...其他配置 }) export class AppModule { } - 修改
MyArtModule:导入SharedModule,这样MyArtComponent就能访问ConfirmAlertComponent了@NgModule({ declarations: [MyArtComponent], imports: [CommonModule, SharedModule], providers: [MyArtService], exports: [MyArtComponent] }) export class MyArtModule { }
- 修改
针对你的One/Two模块例子的修改
如果要在OneComponent里用<app-two>,需要:
- 在
TwoModule里导出TwoComponent:@NgModule({ declarations: [TwoComponent], imports: [CommonModule], exports: [TwoComponent] // 导出组件 }) export class TwoModule { } - 在
OneModule里导入TwoModule:@NgModule({ declarations: [OneComponent], imports: [CommonModule, TwoModule], // 导入包含目标组件的模块 exports: [OneComponent] }) export class OneModule { }
为什么不直接在AppModule导出组件?
有些同学可能会想,直接在AppModule里导出ConfirmAlertComponent,然后让MyArtModule导入AppModule——这绝对不可取!会造成循环依赖(AppModule导入了MyArtModule,MyArtModule又导入AppModule),导致项目编译失败,甚至运行时出现奇怪的bug。共享模块才是正确的打开方式。
内容的提问来源于stack exchange,提问作者Sunil Kashyap

