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

                # 初識泛型 如果你還不能夠順利的、思緒清楚的完成上節的答案,僅僅說明我們重復的還不夠。編程其實就是個熟練工,簡單的事情重復做你就是專家;如果僅僅重復還不夠,那就用心做,因為重復的事情認真做你就是贏家! 我們將具體的答案放到了本節最后,個人按自己的實際情況進行查看。 ## 屬性初始化 我們曾經在添加組件中如下初始化`teacher`: ```typescript teacher = { name: '', username: '', email: '', sex: true }; ``` 這當然是可以的。但也有一些的小的弊端,比如當網絡情況不是特別理想的時候,則會出現一些不如愿的情況。比如我們使用如下代碼來模似請求數據時發生了1.5秒的延遲: ```typescript +++ b/first-app/src/app/edit/edit.component.ts @@ -1,6 +1,7 @@ import {Component, OnInit} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {HttpClient} from '@angular/common/http'; +import {delay} from 'rxjs/operators'; @Component({ selector: 'app-edit', @@ -27,6 +28,7 @@ export class EditComponent implements OnInit { const url = 'http://angular.api.codedemo.club:81/teacher/' + id; // 發起請求,成功時并打印請求結果,失敗時打印失敗結果 this.httpClient.get<any>(url) + .pipe(delay(1500)) .subscribe(data => this.teacher = data, error => console.log('失敗', error) ); ``` - ?? 此段為示例擴展代碼,無需記憶。 則會發生在1.5秒前,性別會默認選中男;而1.5秒后,性別又會變成女。 ![image-20210227105729188](https://img.kancloud.cn/c2/0a/c20a9f96e601caa8bd825ceafde60236_1000x490.png) 為了規避這種情況,在初始化時,我們更愿意將其初始化一個空對象`{}`: ```typescript teacher = {} ``` 然后使用`as`來將其標明(強制轉換)為我寫的類型: ```typescript export class EditComponent implements OnInit { // 使用as進行類型轉換 - teacher = ?{ - name: '', - username: '', - email: '', - sex: true + teacher = ?{} as ?{ + name: string, + username: string, + email: string, + sex: boolean }; ``` - ? `=`后面跟的是值。 - ? `as`后面跟的是類型。 使用上述代碼我們將`teacher`賦值為`{}`并將其類型聲明為`{name: string, username: string, email: string, sex: boolean}`。 ## 初識泛型 泛型基本上是所有強類型面向對象語言支持的特性,它的作用簡單來描述就是:統一某個對象(方法)前后的數據格式。 `httpClient.get`方法在默認返回的類型為 `Object`,我們為`teacher`規定了類型后,編輯器則會發生一個編譯錯誤,表示:無法將一個類型為`Object`的變量賦值給特定`{name: string, username: string, email: string, sex: boolean}`類型的變量。這是由于`Object`類型表示一個空對象,該對象上沒有任何屬性,當然也必然不會有`name、username、email、sex`幾個我們也經聲明需要的屬性了。 ![image-20210227115404670](https://img.kancloud.cn/54/46/5446806421c4185f91e04e506fcba84a_1141x272.png) TypeScript近年的份額穩步提升,三個前端框架Angular, Reactive, Vue均投入到了TypeScript的懷抱,與TypeScript強類型能夠在編譯階段檢查出錯誤的特性是分不開的。 `httpClient`除提供了返回`Object`的`get`方法外,還提供了可以指定返回任意類型的`get<T>`方法,這其中的`<T>`是一個**泛型**,**泛**可以理解為廣泛、寬泛,白話文來說便是:你說我是什么類型,我就可以是什么類型;**泛**還可以理解為**規范**,白話文來說便是:你規定了是什么類型,就必須是什么類型。以`httpClient.get<T>`為例: ### 寬泛性 我們可以將這里的`T`換成任意類型,比如: ```typescript httpClient.get<boolean>; httpClient.get<number>; httpClient.get<string>; httpClient.get<{}>; httpClient.get<object>; httpClient.get<{id: number}>; httpClient.get<any>; ``` 表示:我們此時發起的后臺請求,將分別返回`boolean, number...`類型。 而寬泛并不代表任意,在聲明泛型對應的類型時,我們必須嚴格的依照后臺接口的返回情況。確認的說:后臺返回的類型是什么,我們就應該在此泛型中聲明什么樣的數據類型: ```typescript @@ -26,7 +26,7 @@ export class EditComponent implements OnInit { // 拼接請求URL const url = 'http://angular.api.codedemo.club:81/teacher/' + id; // 發起請求,成功時并打印請求結果,失敗時打印失敗結果 - this.httpClient.get<any>(url) + this.httpClient.get<{name: string, username: string, email: string, sex: boolean}>(url) .subscribe(data => this.teacher = data, error => console.log('失敗', error) ); ``` 當然了,我們也可以將后臺返回的類型規定為`any`,表示后臺返回了一個非常非常寬泛類型的數據,該數據有能力給任何類型賦值。比如以下代碼都是合規的: ```typescript const a = null as any; const b: number = a; // 將a賦值為number類型的b const c: string = a; const d: boolean = a; const e: object = a; const f: { id: number } = a; const g: any = a; ``` ### 規范性 寬泛的目的是為了規范,比如我們剛剛在`get<T>`中將`T` 聲明為`{name: string, username: string, email: string, sex: boolean}`,則表示請求成功后的返回值類型也為`{name: string, username: string, email: string, sex: boolean}` ```typescript this.httpClient.get<{ name: string, username: string, email: string, sex: boolean }>(url) .subscribe(??data => this.teacher = data, error => console.log('失敗', error) ); ``` - ?? data的類型與規定的泛型類型相一致 此時,如若我們想獲取規定泛型上沒有屬性,比如嘗試獲取返回值類型上的`id`屬性,則會發生編譯錯誤: ![image-20210227124717221](https://img.kancloud.cn/05/0d/050dc9a834dbefc90b446c206b41d650_835x145.png) 所以對于泛型而言:寬泛是方法、規范是目的。 ### 泛型化 最終我們結合泛型,調用`httpClient.get<T>`方法,最終代碼如下: ```typescript constructor(private activeRoute: ActivatedRoute, @@ -26,8 +26,8 @@ export class EditComponent implements OnInit { // 拼接請求URL const url = 'http://angular.api.codedemo.club:81/teacher/' + id; // 發起請求,成功時并打印請求結果,失敗時打印失敗結果 - this.httpClient.get<any>(url) - .subscribe(data => this.teacher = data, + this.httpClient.get<{ name: string, username: string, email: string, sex: boolean }>(url) + .subscribe(data => this.teacher = data, error => console.log('失敗', error) ); } ``` ## 本節作業 作業一:程序開發時有個重要原則:(非必要)不造重復的輪子,而我們在當前代碼中出現了重復的`{ name: string, username: string, email: string, sex: boolean }` 分別位于: ```typescript teacher = {} as { name: string, username: string, email: string, sex: boolean }; this.httpClient.get<{ name: string, username: string, email: string, sex: boolean }>(url) ``` - 寫法不同而已,前面的寫成了多行,后臺的寫成了一行。 作業二:打開`scr/app/app.component.ts`,找到其`teachers`聲明的代碼,將其類型由`any[]`改成更規范的格式。 ```typescript // 初始化教師數組 teachers = [] as any[]; ``` 請搜索相關的知識,將兩個重復的輪子變成一個。 | 名稱 | 地址 | 備注 | | ------------------ | ------------------------------------------------------------ | ---- | | TypeScript基礎類型 | [https://www.tslang.cn/docs/handbook/basic-types.html](https://www.tslang.cn/docs/handbook/basic-types.html) | | | TypeScript泛型 | [https://www.tslang.cn/docs/handbook/generics.html](https://www.tslang.cn/docs/handbook/generics.html) | | | 初識泛型 | [http://www.hmoore.net/yunzhiclub/springboot_angular_guide/1369061](http://www.hmoore.net/yunzhiclub/springboot_angular_guide/1369061) | | | 本節源碼 | [https://github.com/mengyunzhi/angular11-guild/archive/step2.4.4.zip](https://github.com/mengyunzhi/angular11-guild/archive/step2.4.4.zip) | | ------ ## 上節答案 ```typescript +++ b/first-app/src/app/edit/edit.component.ts @@ -8,7 +8,14 @@ import {HttpClient} from '@angular/common/http'; styleUrls: ['./edit.component.css'] }) export class EditComponent implements OnInit { - teacher: any; + // 使用as進行類型轉換 + teacher = {} as { + name: string, + username: string, + email: string, + sex: boolean + }; + constructor(private activeRoute: ActivatedRoute, private httpClient: HttpClient) { } @@ -19,10 +26,13 @@ export class EditComponent implements OnInit { // 拼接請求URL const url = 'http://angular.api.codedemo.club:81/teacher/' + id; // 發起請求,成功時并打印請求結果,失敗時打印失敗結果 - this.httpClient.get(url) + this.httpClient.get<any>(url) .subscribe(data => this.teacher = data, error => console.log('失敗', error) ); } + onSubmit(): void { + console.log('點擊提交按鈕'); + } } ``` ```html +++ b/first-app/src/app/edit/edit.component.html @@ -1,16 +1,19 @@ {{teacher | json}} -<div> - 姓名:<input value="張三"> -</div> -<div> - 用戶名:<input value="zhangsan"> -</div> -<div> - Email: <input value="zhangsan@yunzhi.club"> -</div> -<div> - 性別:<input type="radio" checked="true">男 <input type="radio">女 -</div> -<div> - <button>保存</button> -</div> +<form (ngSubmit)="onSubmit()"> + <div> + 姓名:<input value="張三" name="name" [(ngModel)]="teacher.name"> + </div> + <div> + 用戶名:<input value="zhangsan" name="username" [(ngModel)]="teacher.username"> + </div> + <div> + Email: <input value="zhangsan@yunzhi.club" name="email" [(ngModel)]="teacher.email"> + </div> + <div> + 性別:<input type="radio" name="sex" [value]="true" [(ngModel)]="teacher.sex">男 + <input type="radio" name="sex" [value]="false" [(ngModel)]="teacher.sex">女 + </div> + <div> + <button>保存</button> + </div> +</form> ```
                  <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>

                              哎呀哎呀视频在线观看