先來張本章節最終效果圖
css
- 抽離公共項,優化引入方式
- 添加樣式,使咱們的項目更加美觀
- 建立動態表格組件
- 配置頁面生成文件,自動化生成
重複的代碼就是失敗的代碼,因此寫代碼也是一個持續優化的過程。
咱們須要用到增刪改查,上一章利用 dynamic-form.service.ts
完成了「增」的操做,如今利用一樣的文件,完成咱們的查詢工做,既然用到同一個服務,因此咱們須要把文件抽離,讓它更像一個公共文件。html
dynamic-form/dyanmic-form.service.ts
-> api/http/dynamic.service.ts
node
import { Observable } from 'rxjs/Observable'; import 'rxjs/Rx'; import { Injectable } from "@angular/core"; import { HttpClient, HttpEvent, HttpHeaders } from "@angular/common/http"; import { HttpComponentUtil } from '../../../pages/api/http/http.service'; import { HandleService } from '../../../pages/api/http/handle.service'; @Injectable() export class DynamicService { constructor( private http: HttpClient, private https: HttpComponentUtil, private handleService: HandleService ) {} public getList(url: string, params: {} = {}): Observable<any> { let api_url: string = this.https.getUrl(url); return this.http.get(api_url, params) .map((res: any) => (<any>this.handleService.handleStatus(res)).value || undefined) .catch(err => this.handleService.handleError(err)); } /** * * * @param {string} url * @param {{}} [params={}] 請求入參的 body,參數 * @returns {Observable<any>} 返回一個可供訂閱的觀察者對象 * @memberof DynamicService * * */ public saveQuery(url: string, params: {} = {}): Observable<any> { let api_url: string = this.https.getUrl(url); // 利用公用的 http 服務,拼接獲取url return this.http.post(api_url, params, { headers: this.https.headers }) .map((res: any) => (<any>this.handleService.handleStatus(res)).value || undefined) // 捕獲錯誤碼 .catch(err => this.handleService.handleError(err)); // 捕獲系統錯誤 } }
如上述代碼,同時添加一個 getList 方法,讓它有了查詢的功能,如今還須要作兩件事情,先思考一下git
api/index.ts
導出這個服務,使其自動注入到 PagesModule
中dynamic-form.service.ts
及相關信息把時間都用在 如何找尋相對路徑 這個問題上,是很是浪費時間的一件事情
在此以前,項目的引入方式都是相對路徑,咱們如今來修改配置,而後使路徑引入變成相對路徑,這裏須要修改tsconfig.json
github
... "paths": { "@angular/*": ["../node_modules/@angular/*"], "@components/*": ["../src/app/theme/components/*"], "@api/*": ["../src/app/pages/api/*"] } ...
其中有一個選項,在以前升級的過程當中已經添加,根據第一項,能夠推斷出新增的兩個選項的用途,在下面的教程中會統一使用該方式引入,在後面配置問題將再也不重複,須要讀者自行添加。
注意:在配置完成後,須要從新啓動項目使配置生效。npm
好看的網頁離不開優秀的設計,咱們須要盡咱們所能,優化頁面的樣式。
在此以前,項目尚未重置過樣式,因此咱們須要去優化一下咱們的樣式json
npm i reset.css -D
pages.component.ts
api
... import "style-loader!reset.css"; import "style-loader!sweetalert2/dist/sweetalert2.min.css"; import "style-loader!@api/universal/style.scss"; ...
@api/universal/style.scss
瀏覽器
.default-style { h1 { font-size: 30px; font-weight: bold; margin-bottom: 25px; } }
注意:使用 import 引入的樣式將會無差異影響到全部的樣式,因此除了公用樣式,其餘都使用 styleUrls 的方式引入app
在修改代碼的時候,大概 60%-70% 的時間都在讀以前的代碼。
咱們須要建立一個動態表格組件,對應的咱們應該先建立一些聲明文件,做爲起步,同時也可讓本身知道本身在創造什麼,項目結構以下圖。
和動態表單相似,咱們先建立dynamic-table-base/tableItem-base.ts
export class TableBase { controlType: string; // 類型 title: string; // 值,類型可選 key: string; // 字段名 order: number; // 排序 constructor( options: { controlType?: string; title?: string; key?: string; order?: number; } = {} ) { // 設置各個值的默認值 this.controlType = options.controlType || ""; this.title = options.title || ""; this.key = options.key || ""; this.order = options.order || 0; } }
dynamic-table-base/tableItem-text.ts
import { TableBase } from './tableItem-base'; export class TextTable extends TableBase { controlType = 'text'; constructor(options: {} = {}) { super(options); } }
dynamic-table/table-base.ts
export interface TableConfig { url: string; params?: TableParams; } // 請求接口的一些參數 interface TableParams { pageSize?: number; pageNumber?: number; }
準備工做到此結束,如今準備來建立咱們的動態表格組件
開發組件時,須要考慮可擴展性
咱們的表格組件應該有展現功能,規定顯示幾列,每一列的內容應該由頁面傳入,數據來源的 url 應該也由頁面配置傳入,因此咱們會有兩個 Input
屬性。
每一行的內容,由數據內容決定,例若有三條數據,應顯示三行數據,數據由組件自身請求獲取,因此應該有一個自身的屬性用於承載數據。
export class DynamicTableComponent implements OnInit{ @Input() config: TableConfig; @Input() tableControls: TableBase[]; public tableDatas: any[]; }
在加載組件時,應該自動請求數據,組件的最終效果以下dynamic-table.component.ts
import { Component, Input, OnInit } from '@angular/core'; import { TableConfig } from "./table-base"; import { TableBase } from "./dynamic-table-base/tableItem-base"; import { DynamicService } from "@api/http/dynamic.service"; @Component({ selector: "dynamic-table", templateUrl: "./dynamic-table.component.html", styleUrls: ["./dynamic-table.component.scss"] }) export class DynamicTableComponent implements OnInit{ @Input() config: TableConfig; @Input() tableControls: TableBase[]; public tableDatas: any[]; constructor(private service: DynamicService) {} private getTableDatas(): void { this.service.getList(this.config.url, this.config.params) .subscribe((res: any[]) => { console.log(res); if (res.length > 0) { this.tableDatas = res; } }) } ngOnInit(): void { this.getTableDatas(); } }
dynamic-table.component.html
<section> <table class="table"> <thead class="thead-default"> <tr> <th *ngFor="let tableControl of tableControls;">{{tableControl.title}}</th> </tr> </thead> <tbody> <!-- 根據數據渲染對應的行數 --> <tr *ngFor="let tableData of tableDatas;"> <!-- 根據控件顯示對應的列 --> <td *ngFor="let tableControl of tableControls"> <ul [ngSwitch]="tableControl.controlType"> <!-- 顯示對應字段的值 --> <li *ngSwitchCase="'text'"> {{tableData[tableControl['key']]}} </li> <!-- 顯示原始數據 --> <li *ngSwitchDefault> {{tableData | json}} </li> </ul> </td> </tr> </tbody> </table> </section>
dynamic-table.component.scss
.table thead tr th { background: rgba(0,0,0,.3); color: #fff; font-size: 16px; border-top: none; } .table tbody > :first-child td { border-top: none; }
這樣動態表格組件的基本樣式就完成,最後別忘了在 nga.module.ts
中註冊該組件。
注意:這裏將 service 換成了 DynamicService
, 因此 form 組件的 service也須要替換,不然會報錯。
組件已經構建完成,頁面的配置和 form 組件的使用方法相似,這裏直接貼代碼
user-list.component.ts
import { Component } from '@angular/core'; import { UserListService } from './user-list.service'; import { TableBase } from '@components/dynamic-table/dynamic-table-base'; import { TableConfig } from '@components/dynamic-table/table-base'; @Component({ selector: 'ngt-user-list', templateUrl: './user-list.component.html', providers: [ UserListService ] }) export class UserListComponent { public userTableControls: TableBase[]; public userTableConfig: TableConfig = { url: "user" }; constructor(private service: UserListService) { this.userTableControls = this.service.getTableControls(); } }
user-list.component.html
<section class="default-style"> <h1> 用戶列表組件 </h1> <dynamic-table [config]="userTableConfig" [tableControls]="userTableControls"></dynamic-table> </section>
user-list/user-list.service.ts
import { Injectable } from "@angular/core"; import { TableBase, TextTable } from "@components/dynamic-table/dynamic-table-base"; @Injectable() export class UserListService { getTableControls() { let tableControls: TableBase[] = [ new TextTable({ key: "id", title: "ID", order: 0 }), new TextTable({ key: "firstName", title: "名稱", order: 1 }), new TextTable({ key: "emailAddress", title: "Email", order: 2 }), new TextTable({ key: "brave", title: "Brave", order: 3 }) ]; return tableControls.sort((a, b) => a.order - b.order); } }
大功告成,如今能夠打開瀏覽器,嘗試先進入新增頁面,新增一個用戶,在成功返回後,會在表格頁面查詢到本身新增的數據,這樣就完成了簡單的數據展現。
如今表格還有幾個優化的點
在後續文章,會陸續添加這些功能!
(此章代碼在ng2-admin 的 dynamic-table 分支上,能夠pull 下來,方便讀者練習)