学生的更新与其它的组件更新大同小异: ## 更新 为了能够更加方法的组织测试,如果某个方法是由V层触发的。则我们更愿意将该方法中使用到的组件属性通过参数传递进来。这样做使该方法更加独立,同时在方法层面上也符合高内聚低耦合的软件工程思想。 在更新某个学生时,要使用到要更新的学生ID以及FormGroup,我们先将这两项信息加到更新的方法上: ```html +++ b/first-app/src/app/student/edit/edit.component.html @@ -1,4 +1,4 @@ -<form class="container-sm" (ngSubmit)="onSubmit()" [formGroup]="formGroup"> +<form class="container-sm" (ngSubmit)="onSubmit(id, formGroup)" [formGroup]="formGroup"> <div class="mb-3 row"> <label class="col-sm-2 col-form-label">名称</label> <div class="col-sm-10"> ``` 对应修改组件C层: ```typescript +++ b/first-app/src/app/student/edit/edit.component.ts @@ -34,7 +34,7 @@ export class EditComponent implements OnInit { this.loadData(this.id); } - onSubmit(): void { + onSubmit(id: number, formGroup: FormGroup): void { } ``` ### 完成功能 完成功能往往是最简单的事情: ```typescript +++ b/first-app/src/app/student/edit/edit.component.ts @@ -34,8 +34,23 @@ export class EditComponent implements OnInit { this.loadData(this.id); } + /** + * 更新 + * @param id id + * @param formGroup 表单组 + */ onSubmit(id: number, formGroup: FormGroup): void { - + const formValue = formGroup.value as { name: string, phone: string, email: string, clazzId: number }; ① + Assert.isString(formValue.name, formValue.phone, formValue.email, '类型必须为字符串'); ② + Assert.isNumber(formValue.clazzId, '类型必须为number'); ② + this.studentService.update(id, { + name: formValue.name, + email: formValue.email, + phone: formValue.phone, + clazz: {id: formValue.clazzId} + }).subscribe(() => { + console.log('更新成功'); + }); } /** ``` 由于在①上使用了`as`将数据类型`看做`我们认为的类型,所以为了避免这种不安全操作可能带来的影响,我们接收使用②的方法来保证①的`as`是符合预期的。 一旦`formGroup.value`的数据格式并不与我们`as`的相同,则会在②处的代码上发生异常。 #### 单元测试 ```typescript +++ b/first-app/src/app/student/edit/edit.component.spec.ts @@ -7,6 +7,7 @@ import {RouterTestingModule} from '@angular/router/testing'; import {ActivatedRoute, RouterModule} from '@angular/router'; import {ClazzSelectModule} from '../../clazz/clazz-select/clazz-select.module'; import {ReactiveFormsModule} from '@angular/forms'; +import {randomNumber} from '@yunzhi/ng-mock-api'; describe('EditComponent', () => { let component: EditComponent; @@ -30,10 +31,20 @@ describe('EditComponent', () => { fixture.detectChanges(); }); - fit('should create', () => { + it('should create', () => { expect(component).toBeTruthy(); }); + fit('onSubmit', () => { + // 发送数据,使用组件使用MockApi返回的数据初始化 + getTestScheduler().flush(); + fixture.autoDetectChanges(); + + // 使用组件中的formGroup来触发onSubmit()方法 + component.onSubmit(component.id as number, component.formGroup); + getTestScheduler().flush(); + }); + ``` ![image-20210610100346424](https://img.kancloud.cn/c4/ec/c4eca5df6386211872f3075a0b025da7_2244x782.png) ## 资源链接 | 链接 | 名称 | | ------------------------------------------------------------ | -------- | | [https://github.com/mengyunzhi/angular11-guild/archive/step7.7.3.zip](https://github.com/mengyunzhi/angular11-guild/archive/step7.7.3.zip) | 本节源码 |