班级选择组件完成后,我们继续完成学生新增组件: ![image-20210412093845312](https://img.kancloud.cn/18/bb/18bb897886ee5c7ddb59a79e4b1aa107_1022x1212.png) ## 初始化 在`src/app`中新建student模块,然后进入该模块新建新增学生组件: ```bash panjie@panjies-iMac app % pwd /Users/panjie/github/mengyunzhi/angular11-guild/first-app/src/app panjie@panjies-iMac app % ng g m student CREATE src/app/student/student.module.ts (193 bytes) ``` 然后进入新建的`stduent`文件夹,并创建新增学生组件: ```bash panjie@panjies-iMac app % cd student panjie@panjies-iMac student % pwd /Users/panjie/github/mengyunzhi/angular11-guild/first-app/src/app/student panjie@panjies-iMac student % ng g c add CREATE src/app/student/add/add.component.css (0 bytes) CREATE src/app/student/add/add.component.html (18 bytes) CREATE src/app/student/add/add.component.spec.ts (605 bytes) CREATE src/app/student/add/add.component.ts (263 bytes) UPDATE src/app/student/student.module.ts (257 bytes) ``` 然后按原型初始化V层文件: ```html <form class="container-sm" (ngSubmit)="onSubmit()" [formGroup]="formGroup"> <div class="mb-3 row"> <label class="col-sm-2 col-form-label">名称</label> <div class="col-sm-10"> <input type="text" class="form-control" formControlName="name"> <small class="text-danger" *ngIf="formGroup.get('name').invalid"> 名称不能为空 </small> </div> </div> <div class="mb-3 row"> <label class="col-sm-2 col-form-label">学号</label> <div class="col-sm-10"> <input type="text" class="form-control" formControlName="number"> <small class="text-danger" *ngIf="formGroup.get('number').invalid"> 学号不能为空 </small> </div> </div> <div class="mb-3 row"> <label class="col-sm-2 col-form-label">手机号</label> <div class="col-sm-10"> <input type="text" class="form-control" formControlName="phone"> </div> </div> <div class="mb-3 row"> <label class="col-sm-2 col-form-label">邮箱</label> <div class="col-sm-10"> <input type="text" class="form-control" formControlName="email"> </div> </div> <div class="mb-3 row"> <label class="col-sm-2 col-form-label">班级</label> <div class="col-sm-10"> <app-clazz-select formControlName="clazzId"></app-clazz-select> <small class="text-danger" *ngIf="formGroup.get('clazzId').invalid"> 必须选择班级 </small> </div> </div> <div class="mb-3 row"> <div class="col-sm-10 offset-2"> <button class="btn btn-primary" [disabled]="formGroup.invalid">保存 </button> </div> </div> </form> ``` 对应C层如下: ```typescript import {Component, OnInit} from '@angular/core'; import {FormControl, FormGroup} from '@angular/forms'; @Component({ selector: 'app-add', templateUrl: './add.component.html', styleUrls: ['./add.component.css'] }) export class AddComponent implements OnInit { formGroup = new FormGroup({ name: new FormControl(), number: new FormControl(), phone: new FormControl(), email: new FormControl(), clazzId: new FormControl() }); constructor() { } ngOnInit(): void { } onSubmit(): void { console.log('submit'); } } ``` 对新在模块中引入响应式表单: ```typescript +++ b/first-app/src/app/student/student.module.ts @@ -1,12 +1,14 @@ import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {AddComponent} from './add/add.component'; +import {ReactiveFormsModule} from '@angular/forms'; @NgModule({ declarations: [AddComponent], imports: [ - CommonModule + CommonModule, + ReactiveFormsModule ] }) export class StudentModule { ``` ## 单元测试 在单元测试中同样引入响应式表单: ```typescript +++ b/first-app/src/app/student/add/add.component.spec.ts @@ -1,6 +1,7 @@ import {ComponentFixture, TestBed} from '@angular/core/testing'; import {AddComponent} from './add.component'; +import {ReactiveFormsModule} from '@angular/forms'; describe('AddComponent', () => { let component: AddComponent; @@ -8,7 +9,10 @@ describe('AddComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [AddComponent] + declarations: [AddComponent], + imports: [ + ReactiveFormsModule + ] }) .compileComponents(); }); ``` 最后使用`ng t`加入`fit`,启用学生添加组件的单元测试: ![image-20210412140340871](https://img.kancloud.cn/02/09/02094c24306181be7f64f30e2ca15c5a_1758x192.png) 提示上述错误。在继续修改上述错误前,我们修正下测试的描述,以期以后在发生错误时快速定位到错误的文件位置: ```typescript +++ b/first-app/src/app/student/add/add.component.spec.ts @@ -3,7 +3,7 @@ import {ComponentFixture, TestBed} from '@angular/core/testing'; import {AddComponent} from './add.component'; import {ReactiveFormsModule} from '@angular/forms'; -describe('AddComponent', () => { +describe('student -> AddComponent', () => { let component: AddComponent; let fixture: ComponentFixture<AddComponent>; ``` 好了,本节就到这里。下节中我们共同来修正这个单元测试错误。 ## 本节作业 尝试按下图修正本节最后单元测试出现的错误,未修正成功请继续学习7.2.1小节。 ![image-20210412103338742](https://img.kancloud.cn/9d/f5/9df50ef0ec594819c419800866d1fd1b_2282x450.png) | 名称 | 链接 | | ---------------- | ------------------------------------------------------------ | | 本节源码(含答案) | [https://github.com/mengyunzhi/angular11-guild/archive/step7.2.zip](https://github.com/mengyunzhi/angular11-guild/archive/step7.2.zip) |