Angular2:解决路由共享组件重复声明报错问题
解决Angular多模块共享路由组件的重复声明问题
这个问题的核心原因很明确:Angular要求每个组件只能在一个NgModule的declarations数组中被声明一次,哪怕你是把它用作路由组件也不例外。你现在在EXAMPLE1和EXAMPLE2两个模块里都声明了ProductComponent,这就违反了这个规则,所以才会抛出重复声明的错误。
下面是具体的解决步骤,专门适配路由组件的共享场景:
步骤1:创建共享模块封装ProductComponent
首先我们需要创建一个专门的共享模块(比如ProductSharedModule),把ProductComponent的声明和导出都放在这里——这是Angular共享组件的标准做法,对路由组件同样有效:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ProductComponent } from './product.component'; // 根据你的项目实际路径调整 @NgModule({ declarations: [ ProductComponent // 在这里唯一声明该组件 ], imports: [ CommonModule // 如果组件用到了*ngIf、*ngFor这类通用指令,必须导入这个模块 ], exports: [ ProductComponent // 导出组件,让其他导入该共享模块的业务模块能访问它 ] }) export class ProductSharedModule { }
步骤2:修改两个业务模块的配置
接下来,我们需要修改EXAMPLE1和EXAMPLE2模块,移除对ProductComponent的直接声明,转而导入我们刚创建的共享模块:
修改EXAMPLE1.module.ts
... // 导入共享模块 import { ProductSharedModule } from '../../product/product-shared.module'; // 仍然需要导入ProductComponent用于路由配置 import { ProductComponent } from '../../product/product.component'; export const routes:Routes = [ { path: 'products/:product-slug', component: ProductComponent }, // 其他Example1路由 ]; @NgModule({ imports: [ CommonModule, ProductSharedModule, // 加入共享模块 ... ], declarations: [ // 移除ProductComponent的声明! // 其他Example1专属组件 ], providers: [ ... ] }) // 注意:你的类名原来写错了,建议改成EXAMPLE1Module,符合Angular命名规范 export class EXAMPLE1Module { }
修改EXAMPLE2.module.ts
... import { ProductSharedModule } from '../../product/product-shared.module'; import { ProductComponent } from '../../product/product.component'; export const routes:Routes = [ { path: 'different/:product-slug', component: ProductComponent }, // 其他Example2路由 ]; @NgModule({ imports: [ CommonModule, ProductSharedModule, ... ], declarations: [ // 移除ProductComponent的声明! // 其他Example2专属组件 ], providers: [ ... ] }) // 同样修正类名为EXAMPLE2Module export class EXAMPLE2Module { }
为什么这个方案有效?
- 共享模块承担了唯一声明
ProductComponent的职责,完全符合Angular的组件声明规则; - 通过
exports数组暴露组件后,任何导入该共享模块的业务模块都可以将其用作路由组件或普通组件; - 路由配置中直接引用
ProductComponent是完全合法的,因为共享模块已经让该组件对当前业务模块可见了。
另外提个小细节:你原来的模块类名(EXAMPLE1、EXAMPLE2)不符合Angular的命名规范,建议改成EXAMPLE1Module和EXAMPLE2Module,避免代码混淆。
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

