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

                分頁是一個web項目的必備功能。本節讓我們看看一個真實分頁數據到底長啥樣? 當前后臺提供了一個不需要登錄認證的教師分頁接口,具體信息如下: ```bash GET /teacher/page ``` | **類型Type** | **名稱Name** | **描述Description** | 必填 | **類型Schema** | 默認值 | | :------------ | :----------- | :----------------------- | ---- | :----------------------------------------------- | --------- | | Param請求參數 | `page` | 第幾頁 | 否 | `number` | 0 | | Param請求參數 | `size` | 每頁大小 | 否 | `number` | 20 | | Param請求參數 | sort | 排序字段及方式(支持多個) | 否 | `string`例:`sort=name,desc` | `id,desc` | | Response響應 | | Status Code: 200 | | `{content: Teacher[], 其它與分頁排序相關的信息}` | | 如上,該接口接收3個請求參數 ,分別為請求的當前頁page,每頁大小size,以及排序sort。請求成功時將返回狀態碼200,返回數據格式為對象。我們使用瀏覽器直接訪問當前地址,看看返回的分頁數據到底長什么樣子: ![image-20210330092017951](https://img.kancloud.cn/62/e1/62e1211553541fac875d83d73d92f8c8_922x151.png) 這樣的結果看起來亂糟糟的,那就打開控制臺后找到網絡選項卡,刷新后再看看吧: ![image-20210330092111020](https://img.kancloud.cn/11/14/11141ea298afb0cc3289d07971191508_1906x426.png) 我們發現該對象的`content`屬性存放著返回的主體內容,即當前頁對應的教師數組,以外還有很多其它的屬性: ```json { "content": Teacher[], "pageable": { "sort": { "sorted":true, "unsorted":false, "empty":false }, "offset":0, "pageNumber":0, "pageSize":10, "unpaged":false, "paged":true }, "last":true, ?? "totalPages":1, ?? "totalElements":2, ?? "size":10, "number":0, ?? "numberOfElements":2, ?? "sort": { "sorted":true, "unsorted":false, "empty":false }, "first":true, ?? "empty":false } ``` ![image-20210329174345386](https://img.kancloud.cn/54/34/54344cf6330df3db3b636fde8b73757f_746x128.png) 參考上節的分頁原型,我們在此僅將需要使用到的字段使用??進行了標注,各個字段解釋如下: - `last` 當前頁是否為最后一頁 - `totalPages` 共幾頁 - `number`當前為第幾頁(由0開始) - `numberOfElements` 數據總條數 - `first` 當前頁是否為第一頁 至于其它的字段的含義都不難,大概猜一猜吧。 除了返回值外,接口還說自己是支持`page`,`size`,`sort`做為分頁查詢,索性我們再多測試幾個: 第1頁,每頁大小為1,則訪問:[http://angular.api.codedemo.club:81/teacher/page?page=0&size=1](http://angular.api.codedemo.club:81/teacher/page?page=0&size=1)或[http://angular.api.codedemo.club:81/teacher/page?size=1&page=0](http://angular.api.codedemo.club:81/teacher/page?size=1&page=0) 加入按id正向排序,則訪問:[http://angular.api.codedemo.club:81/teacher/page?page=0&sort=id,asc&size=1](http://angular.api.codedemo.club:81/teacher/page?page=0&sort=id,asc&size=1) ## 分頁類 前面我們為了開發的便利性新建過了教師類及班級類,這使得我們可以充分的發揮出TypeSciprt強類型的優勢,減少拼寫錯誤的同時,在IDE的幫助下還能夠在開發時自動填充對象的屬性。 在此我們后臺返回的分頁信息以及我們剛剛確認所需要的字段信息,新建分頁類Page。來到`src/app/entity`文件夾,使用`ng g class page`自動生成: ```bash panjie@panjie-de-Mac-Pro entity % pwd /Users/panjie/github/mengyunzhi/angular11-guild/first-app/src/app/entity panjie@panjie-de-Mac-Pro entity % ng g class page Your global Angular CLI version (11.2.6) is greater than your local version (11.0.7). The local Angular CLI version is used. To disable this warning use "ng config -g cli.warnings.versionMismatch false". CREATE src/app/entity/page.spec.ts (146 bytes) CREATE src/app/entity/page.ts (22 bytes) ``` 接著在其中初始化如下字段: ```typescript /** * 分頁. * @author 河北工業大學夢云智開發團隊 */ export class Page { content: []; last: boolean; number: number; size: number; numberOfElements: number; first: boolean; } ``` ### 添加泛型 由于分頁中的`content`數組中元素的類型是不確定的,比如在教師分頁時`content`中的元素類型為`Teacher`,而在班級分頁時`content`中的元素類型為`Clazz`。所以此時我們需要一個**泛型**來表示`content`中的數組元素類型需要根據使用時的情況確定。 ```typescript +++ b/first-app/src/app/entity/page.ts @@ -2,8 +2,8 @@ * 分頁. * @author 河北工業大學夢云智開發團隊 */ -export class Page { - content: []; +export class Page<T> { + content: T[]; last: boolean; number: number; size: number; ``` 我們在`Page`后面增加了`<T>`以表示該類中有些屬性的類型需要在使用時指定,我們把這個`T`應該用在`content`字段上。這樣一來,便達到了使用`const page = new Page<Teacher>()`時則將`content`的類型設置為`Teacher[]`;而當使用`const page = new Page<Clazz>()`時則將`content`的類型設置為`Clazz[]`的目的。 ### 構造函數 最后新建構造函數,并在其中對其屬性完成初始化操作: ```typescript constructor(data①: { content: T[], ② last?: boolean, ③ number: number, ② size: number, ② numberOfElements: number, ② first?: boolean ③ }) { this.content = data.content; this.number = data.number; this.size = data.size; this.numberOfElements = data.numberOfElements; if (data.last !== undefined) { this.last = data.last; } else { this.last = (this.number + 1) * this.size >= this.numberOfElements ? true : false; ④ } if (data.first !== undefined) { this.first = data.first; } else { this.first = this.number === 0 ? true : false; ⑤ } } ``` 需要注意的時,在構造函數中我們使用了一些小技巧: - ① 我們并沒有為參數`data`設置默認值,這是由于我們認為在使用`Page`時必須在設置參數`data`的值。 - ② 我們為`data`規定了幾個必填屬性,因為我們認為這些屬性是必然設置的,否則`Page`將無法正常工作。 - ③ 我們為`data`規定了幾個選填屬性,因為我們認為這些屬性可以不設置,即使沒有設置,我們的`Page`仍然可以正常工作。 - ④ 當構造函數中未傳入`last`字段時,可能通過計算當前頁、每頁大小、總條數三者間的關系來計算出當前是否為最后一頁。 - ⑤ 當構造函數中未傳入`first`字段時,可以判斷當前頁碼是否為0來計算出當前是否為第一頁。 我們比較容易犯兩個小毛病,一個毛病是懶,第二個是自信。比如我們剛剛在構造函數中寫了一些小在邏輯,但該邏輯就真的一點也沒有問題嗎?這時候就需要克服一下懶和自信的毛病,寫一些代碼測試一下: ```typescript +++ b/first-app/src/app/entity/page.spec.ts fit('should create an instance', () => { // 不加入last, first初始化 let page = new Page({ number: 2, size: 20, numberOfElements: 200, content: [] }); expect(page).toBeTruthy(); expect(page.first).toBeFalse(); expect(page.last).toBeFalse(); // 第1頁,首頁 page = new Page({ number: 0, size: 20, numberOfElements: 200, content: [] }); expect(page.first).toBeTrue(); expect(page.last).toBeFalse(); // 共41條數據,當前第3頁,每頁20條,所以當前頁為尾頁 page = new Page({ number: 2, size: 20, numberOfElements: 41, content: [] }); expect(page.first).toBeFalse(); expect(page.last).toBeTrue(); }); ``` ![image-20210330101908501](https://img.kancloud.cn/3a/c3/3ac368cce5f22769c4e0ef1025bd9b96_626x118.png) ## 初始化C層 接下來我們使用剛剛建立的`Page`類來初始化C層: ```typescript +++ b/first-app/src/app/clazz/clazz.component.ts export class ClazzComponent implements OnInit { + // 默認顯示第1頁的內容 + page = 0; + // 每頁默認為3條 + size = 3; + + // 初始化一個有0條數據的 + pageData = new Page<Clazz>({ + content: [], + number: this.page, + size: this.size, + numberOfElements: 0 + }); + constructor() { } ``` 上述代碼我們增加了三個屬性,并分別設置了默認值。接下來我們在C層中的`ngOnInit()`方法中模擬生成分頁數據: ```typescript +++ b/first-app/src/app/clazz/clazz.component.ts ngOnInit(): void { const clazzes = new Array<Clazz>(); for (let i = 0; i < this.size; i++) { clazzes.push(new Clazz({ id: i, name: '班級', teacher: new Teacher({ id: i, name: '教師' }) })); } this.pageData = new Page<Clazz>({ content: clazzes, number: 2, size: this.size, numberOfElements: 20 }); } ``` ## V層對接 C層模擬數據準備好后,我們來到V層完成對接。首先刪除原來的測試數據,僅保留有用的表頭和基礎結構: ```html <div class="row"> <div class="col-12 text-right"> <a class="btn btn-primary mr-2"><i class="fas fa-plus"></i>新增</a> </div> </div> <table class="table table-striped mt-2"> <thead> <tr class="table-primary"> <th>序號</th> <th>名稱</th> <th>班主任</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> <nav class="row justify-content-md-center"> <ul class="pagination col-md-auto"> <li class="page-item disabled"><a class="page-link" href="#">上一頁</a></li> <li class="page-item active"><a class="page-link" href="#">1</a></li> <li class="page-item"><a class="page-link" href="#">2</a></li> <li class="page-item"><a class="page-link" href="#">3</a></li> <li class="page-item"><a class="page-link" href="#">下一頁</a></li> </ul> </nav> ``` 接著引入`*ngFor`完成班級的循環輸出: ```html +++ b/first-app/src/app/clazz/clazz.component.html @@ -14,6 +14,19 @@ </tr> </thead> <tbody> + <tr *ngFor="let clazz of pageData.content; index as index"> + <td>{{index + 1}}</td> + <td>{{clazz.name}}</td> + <td>教師姓名</td> + <td> + <a class="btn btn-outline-primary btn-sm"> + <i class="fas fa-pen"></i>編輯 + </a> + <span class="btn btn-sm btn-outline-danger"> + <i class="far fa-trash-alt"></i>刪除 + </span> + </td> + </tr> </tbody> ``` ![image-20210330104757923](https://img.kancloud.cn/f5/6f/f56f1250413377a4389d9a2c83cfdf2e_1582x448.png) 最后顯示班主任的姓名,由于`clazz`中存在`teacher`屬性,所以在V層中可以非常輕構地顯示班主任姓名: ```html - <td>教師姓名</td> + <td>{{clazz.teacher.name}}</td> ``` 最終效果如下: ![image-20210330105031585](https://img.kancloud.cn/c4/65/c46558ff3969b5396bfb9a09137ca663_1308x364.png) ## 本節作業 和后臺的提供的教師分頁接口相同,后臺還提供了一個班級分頁接口: ```bash GET /clazz/page ``` | **類型Type** | **名稱Name** | **描述Description** | 必填 | **類型Schema** | 默認值 | | :------------ | :----------- | :----------------------- | ---- | :--------------------------- | --------- | | Param請求參數 | `page` | 第幾頁 | 否 | `number` | 0 | | Param請求參數 | `size` | 每頁大小 | 否 | `number` | 20 | | Param請求參數 | sort | 排序字段及方式(支持多個) | 否 | `string`例:`sort=name,desc` | `id,desc` | | Response響應 | | Status Code: 200 | | `Page<Clazz>` | | 請根據該接口,建立相應的MockApi,在組件中應用MockApi來達到模擬獲取后臺數據的目的。 | 名稱 | 鏈接 | | -------------- | ------------------------------------------------------------ | | REST分頁及排序 | [https://docs.spring.io/spring-data/rest/docs/3.4.6/reference/html/#paging-and-sorting](https://docs.spring.io/spring-data/rest/docs/3.4.6/reference/html/#paging-and-sorting) | | 本節源碼 | [https://github.com/mengyunzhi/angular11-guild/archive/step6.3.2.zip](https://github.com/mengyunzhi/angular11-guild/archive/step6.3.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>

                              哎呀哎呀视频在线观看