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

                # 管道 `pipe`管道在大部分框架中又被稱為`filter`過濾器。無論是管道還是過濾器,只是叫法不同而且,它們的作用都是用來進行數據的轉換。 在中學的化學實驗中,我們在進行物質的過濾的時候接觸過過濾器。有村里蓋房子的時候,我們通常要把沙子中的過大的顆粒過濾出來,也接觸過過濾器。但在現實生活中,過濾器往往只會把多的東西過濾少了,且過濾后的物質必然存在于過濾前的物質之中。而我們此時提的過濾器,功能遠遠不止不此。它不止可以把多的過濾少了,把粗的過濾精了,還可以把少的過濾多了,把有的過濾沒了,甚至于把一種物質過濾成另一種物質。 > 計算機的過濾器的作用可以描述為:`把原有的數據按固定的規則轉換成另外一種數據`。 在Angular中只所以將這種數據格式轉換的功能稱為`管道`,我想是為了突顯多`管道`連接的特點。在Angular中,我們可將多個`管道`連接在一起使用。數據由第一個管道的入口進去,最終由最后一個管道的出口出來。在現實生活中,我們鋪設的管道也是將一節節短的管道首尾連接,最終形成長長的管道線的。 ![image-20210308085811791](https://img.kancloud.cn/65/eb/65eb0bc3d6384356452b1356ac87a680_1252x448.png) 如上為石油管理,石油由管道的一頭流入,其依次通過每一節管道后,最終由管道的那一頭流出。 ## 初始化性別管道 我們在上節的作業中,要求大家將true與false在輸出時轉換為男和女,這可以通過前面學習過的`ngIf`來快速實現。而使用管道的方法,也夠使V層的代碼更加的簡介,也使得我們編寫的代碼更容易被測試,從而達到解耦以及提升代碼健壯性的目的。 使用Angular Cli能夠快速的初始化一個管道。在此,我們初始化一個在管道的這頭輸入true、false,在管道的那頭輸入男女的性別管道---- sexPipe。 該管道暫時只有個人中心組件使用,所以我們將其建立在個人中心組件的文件夾下,使用shell進入`src/app/personal-center`文件夾,并執行以下命令: ```bash panjiedeMacBook-Pro:personal-center panjie$ ng g p sex CREATE src/app/personal-center/sex.pipe.spec.ts (175 bytes) CREATE src/app/personal-center/sex.pipe.ts (211 bytes) UPDATE src/app/app.module.ts (1065 bytes) ``` 該過程與創建組件、類的過程基本相同,為我們創建一個主體文件,一個測試文件,同步更新了該pipe所在的模塊。與組件性質相同,管道同樣是模塊的一部分,所以同樣被聲明在`declarations`中: ```typescript +++ b/first-app/src/app/app.module.ts @@ -11,6 +11,7 @@ import {RouterModule} from '@angular/router'; import {LoginComponent} from './login/login.component'; import {IndexComponent} from './index/index.component'; import { PersonalCenterComponent } from './personal-center/personal-center.component'; +import { SexPipe } from './personal-center/sex.pipe'; @NgModule({ @@ -20,7 +21,8 @@ import { PersonalCenterComponent } from './personal-center/personal-center.compo EditComponent, LoginComponent, IndexComponent, - PersonalCenterComponent + PersonalCenterComponent, + SexPipe ], imports: [ ``` ![image-20210308091837891](https://img.kancloud.cn/5e/00/5e0049efb5dee017420d8d31e0afca57_1392x532.png) ## 初識管道 在管道中僅存在一個`transform`方法: ```typescript transform(value: unknown, ...args: unknown[]): unknown { return null; } ``` 在方法的參數中:`value`做為流入值,流出值由方法中的`return`決定。比如無論注入什么,我們都流出`天職師大`,就可以這樣寫: ```typescript +++ b/first-app/src/app/personal-center/sex.pipe.ts @@ -6,7 +6,8 @@ import {Pipe, PipeTransform} from '@angular/core'; export class SexPipe implements PipeTransform { transform(value: unknown, ...args: unknown[]): unknown { - return null; + console.log('流入', value); + return '天職師大'; } } ``` 此時,我們便可以將該管道加入到相應的V層文件中了。在加入時,需要使用管道的標識,該標識位于管道文件的如下位置: ```typescript @Pipe({ name: 'sex' ?? }) export class SexPipe implements PipeTransform { ``` 將該標識加到對應的V層代碼中,則將自動調用該管道的`transform`方法完成數據的轉換: ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.html @@ -28,7 +28,7 @@ 性別: </div> <div class="col-8"> - {{me.sex}} + {{me.sex | sex}} </div> </div> </div> ``` `|`又稱為`管道符`,它就像一個豎直的管道。在該管道符后接管道標識`sex`,將使用`sexPipe`來過濾`me.sex`,最終在前臺顯示的為過濾器的值。 ## 測試 我們使用`ng t`來啟動個人中心組件后,得到了如下錯誤提示: ![image-20210308092857993](https://img.kancloud.cn/58/a3/58a30828a1d5879073a84957c946fcea_1564x174.png) 這是由于當前啟動的動態測試組件中并沒有聲明`sexPipe`,所以在解析V層的時發現了不在自己能力范圍內的`sex`管道。按我們在前面剛剛總結的模塊的組成,發現不難解決該問題: ![image-20210308091837891](https://img.kancloud.cn/5e/00/5e0049efb5dee017420d8d31e0afca57_1392x532.png) ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.spec.ts @@ -1,6 +1,7 @@ import {ComponentFixture, TestBed} from '@angular/core/testing'; import {PersonalCenterComponent} from './personal-center.component'; +import {SexPipe} from './sex.pipe'; describe('PersonalCenterComponent', () => { let component: PersonalCenterComponent; @@ -8,7 +9,7 @@ describe('PersonalCenterComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [PersonalCenterComponent] + declarations: [PersonalCenterComponent, SexPipe] }) .compileComponents(); }); ``` 最終測試結果如下: ![image-20210308093040552](https://img.kancloud.cn/56/28/56281103e920e3c1a6ce30ff61093f63_1176x396.png) 可見管道中的`transform`方法被執行,成功的接收到了輸入值,輸出值也成功的顯示在了V層上。 ## 完成功能 性別的過濾功能很簡單,如果是true就返回男,如果是false便返回女: ```typescript +++ b/first-app/src/app/personal-center/sex.pipe.ts @@ -6,8 +6,11 @@ import {Pipe, PipeTransform} from '@angular/core'; export class SexPipe implements PipeTransform { transform(value: unknown, ...args: unknown[]): unknown { - console.log('流入', value); - return '天職師大'; + if (value === true) { + return '男'; + } else { + return '女'; + } } } ``` ![image-20210308093349596](https://img.kancloud.cn/a3/91/a39101e9bc46c46b53a1f97d2cb3da8b_608x260.png) ## 不挖坑 不怕神一樣的對手,就怕豬一樣的隊友。如果你在類似LOL的游戲中也曾被豬一樣的隊友坑過,如果我們也不小心做過豬一樣的隊友。那么相信你絕對深知**不挖坑**的意義之所在。 其實大多數的時候,并不是我們的隊友想挖坑,而是他不知不覺的就挖了坑。剛剛我們貌似完成了性別管道的功能,看其實不然。 比如該管道在`transform`方法的參數中將value聲明為`unknown`未知類型,但實際上我們卻只支持`boolean`類型;再比如`transform`方法將返回值類型同樣聲明為`unknown`未知類型,但實際上卻為`string`類型。這些看似不起眼的類型不統一,會給隊友造成極大的因擾。因為隊友再調用該pipe時,僅僅關心輸入與輸出,并不會也不應該關心我們內部的實現原理。 所以我們應該顯示的聲明方法參數類型以及返回值類型,以供其它隊友參考: ```typescript +++ b/first-app/src/app/personal-center/sex.pipe.ts @@ -5,7 +5,7 @@ import {Pipe, PipeTransform} from '@angular/core'; }) export class SexPipe implements PipeTransform { - transform(value: unknown, ...args: unknown[]): unknown { + transform(value: boolean): string { if (value === true) { return '男'; } else { ``` 解決了上述問題后,則應該充分的考慮變量的類型。在javascript中,有兩個特殊的值`undefined`、`null`,一個代表未定義,另一個代表值為空。而我們的上述代碼中并沒有處理上述值。這將導致:將未設置性別的教師性別顯示為女,為此我們進行如下修正: ```typescript +++ b/first-app/src/app/personal-center/sex.pipe.ts @@ -6,6 +6,11 @@ import {Pipe, PipeTransform} from '@angular/core'; export class SexPipe implements PipeTransform { transform(value: boolean): string { + if (value === undefined || value === null) { + console.warn('接收到了空的值'); + return '-'; + } + if (value === true) { return '男'; } else { ``` 如此以來,當傳入的值為`undefined`、`null`時,便會在控制臺打印一條警告信息的同時,輸入`-`字符串。我們簡單測試一下: ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.ts @@ -18,7 +18,7 @@ export class PersonalCenterComponent implements OnInit { 'zhangsan@yunzhi.club', '張三', 'password', - true, + null as unknown as boolean, 'zhangsan' ); } ``` ![image-20210308100442924](https://img.kancloud.cn/b8/2e/b82e16fdbcd58267e57b9adf161d24a7_1242x342.png) ## 單元測試 Angular Cli在生成`SexPipe`時,對應生成了測試文件 src/app/personal-center/sex.pipe.spec.ts。這說明:在進行管道功能的開發時,我們應該啟動當前測試文件,而不是個人中心組件對應的測試文件。在Angular中,對管道進行單獨的測試的方法最簡單,效率最高,效果最好。下面,讓我們將`fit`移至 src/app/personal-center/sex.pipe.spec.ts中: ```typescript +++ b/first-app/src/app/personal-center/sex.pipe.spec.ts @@ -1,7 +1,7 @@ import { SexPipe } from './sex.pipe'; describe('SexPipe', () => { - it('create an instance', () => { + fit('create an instance', () => { const pipe = new SexPipe(); expect(pipe).toBeTruthy(); }); ``` 值得一提的是由于管理只涉及到輸入與輸出,所以測試管道的代碼與測試普通類的方法一致:new一個實例出來,調用相關的方法并對輸出的值進行預測。 > 在軟件開發中,我們把這種**預測**又常被稱為**斷言**,大概表求:我們**斷**定某個結果、狀態的語**言**。 我們根據輸入、輸出進行幾組**預測**如下: ```typescript +++ b/first-app/src/app/personal-center/sex.pipe.spec.ts @@ -3,6 +3,14 @@ import { SexPipe } from './sex.pipe'; describe('SexPipe', () => { fit('create an instance', () => { const pipe = new SexPipe(); - expect(pipe).toBeTruthy();g + expect(pipe).toBeTruthy(); + // 預測輸入true時,輸出男 + expect(pipe.transform(true)).toBe('男'); + // 預測輸入true時,輸出男 + expect(pipe.transform(false)).toBe('女'); + // 預測輸入undefined時,輸出- + expect(pipe.transform(undefined as unknown as boolean)).toBe('-'); + // 預測輸入null時,輸出- + expect(pipe.transform(null as unknown as boolean)).toBe('-'); }); }); ``` 此時,我們執行`ng t`。若`expect`中函數執行的結果與`toBe`中給出的值相同,則方法被正確執行;否則將會拋出異常并中斷執行。這種處理方式保障了方法的結果與我們的預期是相同的,間接的證明了方法的正確性。 ![image-20210308101633635](https://img.kancloud.cn/d1/5d/d15d70246f70db2465a3fb79f344e580_592x118.png) ## 本節作業 我們在填坑的過程中,刪除了`transform(value: unknown, ...args: unknown[]):`中的參數:` ...args: unknown[]`,請查詢`...args`代表的含義,并解釋為什么刪除了該參數也沒有報任何語法錯誤。 | 名稱 | 地址 | | | -------- | ------------------------------------------------------------ | ---- | | 管道 | [https://angular.cn/guide/pipes](https://angular.cn/guide/pipes) | | | 管道測試 | [https://angular.cn/guide/testing-pipes](https://angular.cn/guide/testing-pipes) | | | 本節源碼 | [https://github.com/mengyunzhi/angular11-guild/archive/step4.2.zip](https://github.com/mengyunzhi/angular11-guild/archive/step4.2.zip) | |
                  <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>

                              哎呀哎呀视频在线观看