本文介绍两种在 Angular 中,关于处理父子组件之间关系的代码文件的组织形式。第一种形式是重量级的,我们给每一个组件外面都包裹成模块;第二种则相对比较简单,无需给子组件包裹成模块,只需要在父组件模块中对所需使用的子组件声明即可!
1. 父子组件都具有自己的模块,本质上是合作关系
组件及其模块之间的代码结构如下所示:
plaintext
src/
|-- app/
| |-- parent/
| | |-- parent.component.ts
| | |-- parent.component.html
| | |-- parent.component.css
| | |-- parent.module.ts # 父组件的NgModule
| | |-- parent.component.spec.ts
| |-- child/
| | |-- child.component.ts
| | |-- child.component.html
| | |-- child.component.css
| | |-- child.module.ts # 子组件的NgModule
| | |-- child.component.spec.ts
| |-- shared.service.ts
| |-- app.module.ts # 根模块
|-- assets/
|-- index.html
|-- styles.css
|-- ...
在这个结构中,父组件和子组件各自有自己的NgModule,即parent.module.ts
和child.module.ts
。这样做的原因在于:使它们位于不同的模块或需要组织代码以便于更好的维护和可扩展性,那么为每个组件创建单独的NgModule是有益的。
父组件的NgModule (parent.module.ts):
typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ParentComponent } from './parent.component';
import { ChildModule } from './child/child.module'; // 导入子组件的模块
@NgModule({
declarations: [
ParentComponent // 声明父组件
],
imports: [
CommonModule, // 导入公共模块
ChildModule // 导入子组件的模块,以便父组件可以使用子组件
],
exports: [
ParentComponent // 如果需要在其他NgModule中使用父组件,可以在这里导出
]
})
export class ParentModule { }
子组件的NgModule (child.module.ts):
typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChildComponent } from './child.component';
@NgModule({
declarations: [
ChildComponent // 声明子组件
],
imports: [
CommonModule // 通常需要导入公共模块
],
exports: [
ChildComponent // 如果子组件需要在其他NgModule中使用,可以在这里导出
]
})
export class ChildModule { }
在parent.module.ts
中,我们导入了ChildModule
,这样父组件模块就能够使用子组件。同时,ParentComponent
在declarations
数组中声明,表示它是父模块的一部分。如果父组件需要在其他模块中使用,可以在exports
数组中导出它。
总结
上述的组织方式可以概括为:父子组件都有自己的模块。在子组件模块中,声明然后导出子组件;在父组件模块中声明父组件,导入子组件模块;最后在父组件模板中就可以直接使用子组件了!
2. 子组件就是父组件的下级
当子组件无需形成自己的模块,且只会被一个父组件使用时,你可以直接将子组件声明在父组件的模块中,而无需为子组件创建一个单独的模块。这种情况下,代码文件的组织结构会更为简洁,因为你减少了子组件模块的相关文件。
代码文件的组织结构
plaintext
src/
|-- app/
|-- parent/
|-- parent.component.ts
|-- parent.component.html
|-- parent.component.css
|-- parent.module.ts # 父组件的NgModule,同时声明父组件和子组件
|-- parent.component.spec.ts
|-- child/
|-- child.component.ts
|-- child.component.html
|-- child.component.css
|-- child.component.spec.ts
|-- shared.service.ts
|-- app.module.ts # 根模块
|-- assets/
|-- index.html
|-- styles.css
|-- ...
在这个结构中,子组件的文件仍然被组织在父组件的目录下,但并没有为子组件创建单独的NgModule
。
对应的代码
父组件的NgModule (parent.module.ts):
typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ParentComponent } from './parent.component';
import { ChildComponent } from './child/child.component'; // 直接导入子组件
@NgModule({
declarations: [
ParentComponent, // 声明父组件
ChildComponent // 同时声明子组件
],
imports: [
CommonModule // 导入公共模块
],
exports: [
ParentComponent // 如果需要在其他NgModule中使用父组件,可以在这里导出
// 注意:如果子组件不需要在其他模块中使用,则无需导出
]
})
export class ParentModule { }
子组件 (child.component.ts):
子组件的TypeScript代码不需要改变,它仍然是一个标准的Angular组件。
typescript
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor() { }
ngOnInit() { }
}
在这种情况下,由于子组件没有自己的模块,它会被直接绑定到父组件的模块中。这样做的好处是减少了模块的复杂性,但缺点是如果子组件需要在多个地方复用,你可能需要将它移动到一个单独的模块中,或者在其他需要它的模块中重新声明。这通常适用于紧密耦合的组件,其中子组件是专门为父组件设计的,并且不太可能在其他上下文中使用。
总结
在上面的第二种做法中,无需给子组件包裹成模块;只需在父组件所在目录中创建 children 子目录然后将子组件放置其中即可!然后只需要在父组件所在的模块中声明此子组件即可!