<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                同其它組件的開發步驟一致,我們首先按原型進行前臺的初始化。然后結合單元測試完成各個功能點的開發。待后臺接口準備后(當然也可能是早早的就已經準備好了),對接后臺接口以進行集成測試來對功能進行驗證。并按驗證的結果進行相應前(后)臺修正。 打開shell,并來到學生模塊,執行`ng g c edit`來生成對應的編輯組件: src/app/student ``` panjiedeMac-Pro:student panjie$ ng g c edit CREATE src/app/student/edit/edit.component.sass (0 bytes) CREATE src/app/student/edit/edit.component.html (19 bytes) CREATE src/app/student/edit/edit.component.spec.ts (614 bytes) CREATE src/app/student/edit/edit.component.ts (262 bytes) UPDATE src/app/student/student.module.ts (754 bytes) ``` angular cli自動生成組件的同時,將該組件同步添加到`student.module.ts`中。 ## V層初始化 V層的初始化與添加學生大同小異: src/app/student/edit/edit.component.html ``` <h2>編輯學生</h2> <form (ngSubmit)="onSubmit()" [formGroup]="formGroup"> <label>姓名:<input name="name" formControlName="name"/></label> <label>學號:<input name="sno" formControlName="sno"/></label> <label>班級:<app-klass-select [klass]="student.klass" (selected)="onSelectKlass($event)"></app-klass-select></label> <button type="submit">保存</button> </form> <a style="display: none" routerLink="./../" #linkToIndex>返回學生列表頁</a> ``` > 由于添加與編輯組件具有高度的重合性,所以在有些小的項目中我們也會嘗試將`新增`、`編輯`兩個功能融合到一個組件中。 ## 單元測試及C層初始化 打開`src/app/student/edit/edit.component.spec.ts`,添加`f`并修正單元測試的描述。 ``` fdescribe('student -> EditComponent', () => { ``` 打開控制臺,并使用`ng test`來啟動單元測試,接下來我們按單元測試的提示來完善單元測試文件或C層代碼 ### Failed: Template parse errors: Can't bind to 'formGroup' since it isn't a known property of 'form'. 譯文:失敗的:模板解析錯誤:不能在`form`上綁定`formGroup`,`formGroup`不是`form`元素的已知屬性。 原因:formGroup是響應式表單為form添加的屬性,單元測試未引入響應式表單,所以產生上述錯誤。 解決方案: src/app/student/edit/edit.component.spec.ts ``` beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ EditComponent ], imports: [ ReactiveFormsModule ? ] }) .compileComponents(); })); ``` ### Can't bind to 'klass' since it isn't a known property of 'app-klass-select'. 這錯誤雖然在描述上與上一個相同,但產生的原因卻不盡相同。在解析`<app-klass-select [klass]="student.klass"`時, angular把`<app-klass-select`做為普通的dom元素而進行解析,而普通的dom元素并沒有`[klass]`屬性,因而產生了錯誤。 解決方案:聲明`app-klass-select`對應的組件,這樣在模板解析時遇到`<app-klass-select`便會當成組件來進行處理。 src/app/student/edit/edit.component.spec.ts ``` beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ EditComponent, KlassSelectComponent? ], imports: [ ReactiveFormsModule ] }) .compileComponents(); })); ``` ### Can't bind to 'url' since it isn't a known property of 'app-select'. 我們在V層中并沒有引用`app-select`,出現該錯語的原因是由于`KlassSelectComponent`中引用了`app-select`。但當前測試模塊卻找到對應解析`app-select`的組件。 解決方案:引入解析`app-select`的組件。該組件被聲明于`CoreModule`并由該模塊拋出,所以直接`import CoreModule`即擁有了`app-select`正確的解析器: SelectComponent src/app/student/edit/edit.component.spec.ts ``` beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ EditComponent, KlassSelectComponent ], imports: [ ReactiveFormsModule, CoreModule ? ] }) .compileComponents(); })); ``` ### NullInjectorError: StaticInjectorError(DynamicTestModule)[SelectComponent -> HttpClient]: 譯為:在SelectComponent中注入HttpClient時發生空注入器錯誤:靜態注入器錯誤(當前測試模塊即:動態的測試模塊) 也就是說SelectComponent需要一個能夠提供HttpClient的服務,但卻沒有找到。在非測試環境下,HttpClientModule起到了提供HttpClient的作用,在測試環境下,我們使用HttpClientTestingModule來提供HttpClient以防止其發起真實的HTTP請求。 src/app/student/edit/edit.component.spec.ts ``` beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ EditComponent, KlassSelectComponent ], imports: [ ReactiveFormsModule, CoreModule, HttpClientTestingModule ? ] }) .compileComponents(); })); ``` ### Error: formGroup expects a FormGroup instance 這個錯誤是說:在V層中用到了formGroup,但該formGroup沒有被實例化。該錯誤報的很詳細,不但提醒我們哪錯了,還給出了解決問題的示例代碼: ``` Error: formGroup expects a FormGroup instance. Please pass one in. Example: <div [formGroup]="myGroup"> <input formControlName="firstName"> </div> In your class: this.myGroup = new FormGroup({ firstName: new FormControl() }); error propert ``` 的確,我們雖然在V層中使用了一些變量、方法,但在C層中卻并沒有實例化它們。而單元測試則可以協助我們來完成這些變量的實例化,以避免我們經常犯的"不小落掉一個"的錯誤。 src/app/student/edit/edit.component.ts ```javascript export class EditComponent implements OnInit { formGroup: FormGroup; constructor() { } ngOnInit() { this.formGroup = new FormGroup({ name: new FormControl(''), sno: new FormControl('') }); } } ``` ### TypeError: Cannot read property 'klass' of undefined 但凡出現此類錯誤的,必然是我們調用了`xxx.klass`而此時xxx的值是undefined。觀察V層發現語句:`<app-klass-select [klass]="student.klass"`符合剛才的結論。避免該錯誤的方法也很簡單:初始化student,使其不為undefined src/app/student/edit/edit.component.ts ``` export class EditComponent implements OnInit { formGroup: FormGroup; student: Student = new Student(); ? constructor() { } ``` 至此,我們一步步的打造了一個可以測試`編輯學生組件`的如下模塊: ![](https://img.kancloud.cn/1e/1a/1e1a36dc506a3fa4b4fa38de474668f0_1046x558.png) 該測試模塊`DynamicTestModule`的目標在于調用`createComponent`方法來創建一個可供測試的`編輯學生組件`。在創建`編輯學生組件`的過程中,再依次地創建其依賴的其它組件或服務。而在創建依賴過程中,一旦在本測試模塊找不到應的依賴項,則會報相應的注入錯誤。我們在單元測試模塊中,通過使用declarations及imports的方式為測試模塊添加`編輯學生組件`所有的依賴項后,單元測試順利通過,初始化工作完成。 根據上圖,我們大膽猜測總結出以下規律: 1. 單元測試模塊在創建測試組件時,需要提前準備好該組件所依賴的其它組件及服務。 2. 單元測試模塊`DynamicTestModule`是一個模塊,學生模塊`StudentModule`也是一個模塊,它們都是模塊的個例,那么推廣開來應該能夠得出:模塊在創建相應的組件時,需要提前準備好該組件所依賴的其它組件及服務。如果未準備好,則會引發相應的依賴錯誤。 3. 如果某個模塊擁有某個組件所依賴的其它組件及服務,則該模塊必然擁有創建該組件的能力。 有了以下的總結,讓我們再次閱讀4.5.10集成測試小節,相信此時再次閱讀便輕松多了。只所以出現了`Can't bind to 'formGroup' since it isn't a known property of 'form'.`的錯誤,是由于`formGroup`指令存在于`ReactiveFormsModule`,而此時的`StudentModule`并沒有引用`ReactiveFormsModule`。 # 練一練 按我們總結的規律的第3點:'如果某個模塊擁有某個組件所依賴的其它組件及服務,則該模塊必然擁有創建該組件的能力。',當前的測試模塊不但擁有了創建`編輯學生組件`的能力,同時還擁有了創建`選擇班級組件`及`選擇組件`的能力。請在單元測試中嘗試創建`選擇班級組件`及`選擇組件`兩個組件。并斷言其創建成功。 # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step4.7.1](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step4.7.1) | - |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看