<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>

                上節最后的錯誤是由于在教師列表組件中,使用了相對地址`/clazz/page`請求了后臺數據,而不是絕對地址`http://angular.api.codedemo.club:81/clazz/page`,這樣做最直接的好處就是不需要重復去寫那個又臭又長的前綴了。 ## Api攔截器 前面我們已然接觸了兩個攔截器 ---- 用于與后臺驗證交互的`XAuthTokenInterceptor`以及在用于添加Api請求前綴的`ApiInterceptor`。 將`ApiInterceptor`添加到`AppModule`將使用該攔截器生效: ```typescript +++ b/first-app/src/app/app.module.ts @@ -15,6 +15,7 @@ import { SexPipe } from './personal-center/sex.pipe'; import {XAuthTokenInterceptor} from './x-auth-token.interceptor'; import {WelcomeComponent} from './welcome.component'; import { NavComponent } from './nav/nav.component'; +import {ApiInterceptor} from './api.interceptor'; @NgModule({ @@ -37,7 +38,8 @@ import { NavComponent } from './nav/nav.component'; RouterModule ], providers: [ - {provide: HTTP_INTERCEPTORS, useClass: XAuthTokenInterceptor, multi: true} + {provide: HTTP_INTERCEPTORS, useClass: XAuthTokenInterceptor, multi: true}, + {provide: HTTP_INTERCEPTORS, useClass: ApiInterceptor, multi: true} ], bootstrap: [IndexComponent] }) ``` ## 重復的輪子 `ApiInterceptor`被引用到`AppModule`后,重復的輪子應該到了退出歷史舞臺的時候了: 教師添加組件: ```typescript +++ b/first-app/src/app/add/add.component.ts @@ -26,7 +26,7 @@ export class AddComponent implements OnInit { onSubmit(): void { console.log(this.teacher); this.httpClient - .post('http://angular.api.codedemo.club:81/teacher', this.teacher) + .post('/teacher', this.teacher) .subscribe((result) => { console.log('接收到返回數據', result); this.router.navigate(['teacher']); ``` 教師列表: ```typescript +++ b/first-app/src/app/app.component.ts @@ -18,12 +18,12 @@ export class AppComponent implements OnInit { * 組件初始化完成后將被自動執行一次 */ ngOnInit(): void { - this.httpClient.get<Teacher[]>('http://angular.api.codedemo.club:81/teacher') + this.httpClient.get<Teacher[]>('/teacher') .subscribe(teachers => this.teachers = teachers); } onDelete(id: number): void { - const url = `http://angular.api.codedemo.club:81/teacher/${id}`; + const url = `/teacher/${id}`; ``` 編輯教師: ```typescript +++ b/first-app/src/app/edit/edit.component.ts @@ -21,7 +21,7 @@ export class EditComponent implements OnInit { const id = this.activeRoute.snapshot.params.id; // 拼接請求URL - const url = 'http://angular.api.codedemo.club:81/teacher/' + id; + const url = '/teacher/' + id; // 發起請求,成功時并打印請求結果,失敗時打印失敗結果 this.httpClient.get<Teacher>(url) .subscribe(data => this.teacher = data, @@ -32,7 +32,7 @@ export class EditComponent implements OnInit { onSubmit(): void { console.log(this.teacher); // 獲取ID,拼接URL - const url = 'http://angular.api.codedemo.club:81/teacher/' + + const url = '/teacher/' + this.activeRoute.snapshot.params.id; // 發起請求,更新教師,成功時打印請求結果并刷新教師列表查看效果,失敗時打印失敗結果 this.httpClient.put(url, this.teacher) ``` 登錄: ```typescript +++ b/first-app/src/app/login/login.component.ts @@ -36,7 +36,7 @@ export class LoginComponent implements OnInit { this.httpClient .get<Teacher>( - 'http://angular.api.codedemo.club:81/teacher/login', + '/teacher/login', {headers: httpHeaders}) .subscribe(teacher => this.beLogin.emit(teacher), error => { ``` 個人中心: ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.ts @@ -14,7 +14,7 @@ export class PersonalCenterComponent implements OnInit { } ngOnInit(): void { - const url = 'http://angular.api.codedemo.club:81/teacher/me'; + const url = '/teacher/me'; this.httpClient.get<Teacher>(url) .subscribe(teacher => { console.log('請求當前登錄用戶成功'); ``` ### 單元測試 移除到重復的輪子后,移除項目所有的`fit`,接著使用`ng t`來測試項目已檢測移除工作是否對歷史測試造成了影響。打開控制臺查看異常信息: ![image-20210408154942726](https://img.kancloud.cn/50/1b/501b3dedb10d4c9a94d36facf5d85c07_2198x164.png) 提示說沒有找到`/teacher`請求,該請求發生于教師列表組件的功能中,找到相關的單元測試并加入`ApiInterceptor`: ```typescript +++ b/first-app/src/app/app.component.spec.ts @@ -1,7 +1,8 @@ import {TestBed} from '@angular/core/testing'; import {AppComponent} from './app.component'; -import {HttpClientModule} from '@angular/common/http'; +import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http'; import {RouterTestingModule} from '@angular/router/testing'; +import {ApiInterceptor} from './api.interceptor'; describe('AppComponent', () => { beforeEach(async () => { @@ -13,6 +14,9 @@ describe('AppComponent', () => { declarations: [ AppComponent ], + providers: [ + {provide: HTTP_INTERCEPTORS, useClass: ApiInterceptor, multi: true} + ], }).compileComponents(); }); ``` 其它錯誤: ![image-20210408155451423](https://img.kancloud.cn/48/5b/485bceb57b1a1c29d4650f8566de0784_1292x106.png) 前面兩個錯誤,分別發生在登錄組件: ```typescript +++ b/first-app/src/app/login/login.component.spec.ts @@ -5,6 +5,7 @@ import {FormsModule} from '@angular/forms'; import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http'; import {Teacher} from '../entity/teacher'; import {XAuthTokenInterceptor} from '../x-auth-token.interceptor'; +import {ApiInterceptor} from '../api.interceptor'; describe('LoginComponent', () => { let component: LoginComponent; @@ -18,7 +19,8 @@ describe('LoginComponent', () => { HttpClientModule ], providers: [ - {provide: HTTP_INTERCEPTORS, useClass: XAuthTokenInterceptor, multi: true} + {provide: HTTP_INTERCEPTORS, useClass: XAuthTokenInterceptor, multi: true}, + {provide: HTTP_INTERCEPTORS, useClass: ApiInterceptor, multi: true} ] }) ``` 以及個人中心組件上: ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.spec.ts @@ -2,7 +2,8 @@ import {ComponentFixture, TestBed} from '@angular/core/testing'; import {PersonalCenterComponent} from './personal-center.component'; import {SexPipe} from './sex.pipe'; -import {HttpClientModule} from '@angular/common/http'; +import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http'; +import {ApiInterceptor} from '../api.interceptor'; describe('PersonalCenterComponent', () => { let component: PersonalCenterComponent; @@ -11,7 +12,10 @@ describe('PersonalCenterComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [PersonalCenterComponent, SexPipe], - imports: [HttpClientModule] + imports: [HttpClientModule], + providers: [ + {provide: HTTP_INTERCEPTORS, useClass: ApiInterceptor, multi: true} + ] }) .compileComponents(); }); ``` 此時請求的地址前綴正確,且狀態碼為`401`非`404`了: ![image-20210408160107902](https://img.kancloud.cn/ad/a8/ada81dc600d4888729933f3241bcb407_1440x72.png) `401`是用戶在未登錄的情況下獲取登錄用戶發生在正常錯誤信息。 最后如果我們多刷新幾次單元測試使用的瀏覽器,還可能得到如下錯誤: ![image-20210408160333686](https://img.kancloud.cn/27/39/2739843f6c268ce0a054b9c77fa5b2db_2106x354.png) 該錯誤是`TestBed`的一些惰性加載特性引發的。由于我們在不同的`TestBed`中以不同的方法提供了Http攔截器,不同的攔截器在`TestBed`使用時,被**混用**了。最終引發了上述錯誤。 這就像高峰期去食堂吃飯,烏壓壓的食堂中我剛剛看到了一個空座,當自己打完飯閉上眼走向那個座拉后,卻不想該座位已經被同學占用了。追求根本的原因,是因為我們太懶,不愿意在走路的過程中反復地去更新座位的狀態。我們在后續的章節中將專門的來講解該問題產生的原因以及解決方案。 至此`ApiInterceptor`成功應用到了當前項目中。 ## 本節作業 在`ClazzModule`中添加其它路由,并完善各個組件間的跳轉關系,使整個班級管理模塊完整的工作起來。 ## 注意 本節在去輪子時修正的代碼較多,如果這種變動不小心使你變的混亂,那么在繼續學習以前請下載我們下述鏈接中提供的源碼。 | 名稱 | 鏈接 | | -------- | ------------------------------------------------------------ | | 本節源碼 | [https://github.com/mengyunzhi/angular11-guild/archive/step6.6.2.zip](https://github.com/mengyunzhi/angular11-guild/archive/step6.6.2.zip) | | 所有源碼 | [http://nas.yunzhi.club:5010/sharing/w3oUsMZ7j](http://nas.yunzhi.club:5010/sharing/w3oUsMZ7j) |
                  <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>

                              哎呀哎呀视频在线观看