先来张本章节最终效果图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 下来,方便读者练习)