By
被删
更新日期:
因为项目原因又玩上了Angular2(v4.0+),《玩转Angular2》系列用于探索一些灵活或者新的用法。
本文讲述封装动态列表,通过配置文件生成列表的过程。
动态列表
基本功能
前面我们花了很大的篇幅来制作动态表单的生成和配置,这里我们将制作动态列表的生成。
动态列表相对简单,这里我们提供以下功能:
前面的增删改则是可选的,我们通过配置来定义包含的功能:
1 2 3 4
| export interface IListConfig { function: string[]; content: IList[]; }
|
这里面有个列表展示内容,通常我们的列表除了基本的序号列和操作列,其余的我们都会需要以下的参数:
1 2 3 4
| export interface IList { title: string; key: string; }
|
html模版
通常本骚年创建一些模块或是组件,会先从html模版开始,我们把期望的样子列出来,就能知道还缺哪些功能啦。
- 列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <a class="btn btn-info" *ngIf="hasFunction('add')" (click)="edit(-1)">新建</a> <div class="row" *ngIf="(listConfig && listConfig.content && listConfig.content.length)"> <div class="col-md-6"> <table class="table table-bordered table-striped"> <thead> <tr> <th>序号</th> <th *ngFor="let li of listConfig.content">{{li.title}}</th> <th *ngIf="hasFunction('edit') || hasFunction('remove')">操作</th> </tr> </thead> <tbody> <tr *ngFor="let data of dataModel; let i = index;"> <td>{{i+1}}</td> <td *ngFor="let li of listConfig.content">{{data[li.key]}}</td> <td *ngIf="hasFunction('edit') || hasFunction('remove')"> <a class="btn btn-default" *ngIf="hasFunction('edit')" (click)="edit(i)">编辑</a> <a class="btn btn-danger" *ngIf="hasFunction('remove')" (click)="dataModel.splice(i, 1)">删除</a> </td> </tr> </tbody> </table> </div> </div>
|
这里我们可以看出:
hasFunction()
: 检测是否有某功能并显示
listConfig
: 列表配置,格式符合以上IListConfig
edit()
: 编辑或新建功能,新建传入参数-1
dataModel
: 列表的内容
- 编辑对话框
我们还需要一个编辑对话框,里面是之前封装好的动态表单,故我们还需要创建一个表单配置ICustomControl[]
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div class="modal" *ngIf="hasFunction('edit') || hasFunction('add')" [hidden]="!isShown"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="isShown = false;"><span aria-hidden="true">×</span></button> <h4 class="modal-title">{{isEdit > -1 ? '编辑' : '新建'}}</h4> </div> <div class="modal-body"> <dynamic-form *ngIf="isShown" [config]="formConfig" [(model)]="formModel"></dynamic-form> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal" (click)="isShown = false;">取消</button> <button type="button" class="btn btn-primary" [disabled]="!formModel.valid" (click)="save()">保存</button> </div> </div> </div> </div>
|
这里我们知道:
isShown
: 控制对话框显示,以及动态表单的创建
hasFunction()
: 同上,检测是否有某功能并显示
save()
: 保存修改或新建
formConfig
: 动态表单的配置
js逻辑
通过上面的模版,我们大概知道需要哪些功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| @Component({ selector: 'dynamic-list', templateUrl: './dynamic-list.component.html', }) export class DynamicListComponent { @Input() listConfig: IListConfig; @Input() formConfig: ICustomControl[] = []; @Input() dataModel: any = []; @Input() formModel: any = []; isShown: boolean = false; isEdit: number = -1; hasFunction(fun: string) { if (this.listConfig && this.listConfig.function) { return this.listConfig.function.indexOf(fun) > -1; } return false; } edit(index: number) { this.isEdit = index; if (index > -1) { this.formModel = ObjectCopy(this.dataModel[index]); } else { this.formModel = {}; } this.isShown = true; } save() { const model = ObjectCopy(this.formModel); if (this.isEdit > -1) { this.dataModel[this.isEdit] = model; } else { this.dataModel.push(model); } this.isShown = false; } }
|
至于针对对象的深拷贝,其实也不是很难的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export function ObjectCopy(newObj) { const obj = Object.assign({}, newObj); if (newObj) { Object.keys(newObj).map(key => { if (newObj[key] && !(newObj[key] instanceof Array) && typeof newObj[key] === 'object') { obj[key] = ObjectCopy(newObj[key]); } else { obj[key] = newObj[key]; } }); } return obj; }
|
实例演示
这里假设我们需要以下这样的列表:
- 可进行增删查改。
- 包括名字、性别和备注。
我们的配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| export const formConfig: ICustomControl[] = [ { type: 'text', label: '名字', key: 'name', validations: [{ type: 'required', message: '名字必填' }] }, { type: 'radio', label: '性别', key: 'gender', options: [ {id: 'male', text: '男'}, {id: 'female', text: '女'} ] }, { type: 'text', label: '备注', key: 'remark' } ]; export const listConfig: IListConfig = { function: ['add', 'edit', 'remove'], content: [{ key: 'name', title: '名字' }, { key: 'gender', title: '性别' }, { key: 'remark', title: '备注' }] };
|
这里我们需要主要的是,若希望编辑或创建的对象在列表中能展示,需要两者的key值一致。
效果图如下:
结束语
项目中表单配置部分大致的实现也是差不多告一段落啦,后面可能更多的是补充和优化而已。
而其实项目还可以多种拓展呢,像这样的添加配置像(validations和hiddenWhen)也可以通过抽象做成更加通用的功能。
此处查看项目代码
此处查看页面效果
查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢