现在市面上有大量的JavaScript数据表格控件,包括开源的第三方的和自产自销的。可以说Wijmo的Flexgrid是目前适应Angular 2的最好的表格控件。
Angular 2数据表格基本要求: 更小、更快、更熟悉。
为了使用Angular 2表格,首先你需要了解表格的基本要求。FlexGrid开始于1996年,当时使用C++为Visual Basic编写的控件。多年来,它不断进化并在多个平台得到完善,尤其是JavaScript平台。FlexGrid 因为Flex的理念而命名,控件应当包含最需要的关键功能集和可扩展的能力。内置的基本功能比如:排序、分组、编辑,同时其他比较花哨的东西可以通过可选的扩展来提供。这将会保持控件的精简和高效,同时给了客户深度自定制的能力。
另外一个重要的指标就是性能。FlexGrid不断和其它产品比较,以确保我们足够快。Flex理念使得我们的文件足够小(压缩后约25K),我们对其它的框架没有任何依赖。最显著的性能改进是通过虚拟渲染。FlexGrid虚拟化全部的DOM,每次只绘制需要填充视区的单元格(和一些为使滚动平滑的缓冲区)。当表格滚动,单元格(DOM元素)会被回收。虚拟渲染意味着Grid可以在1秒内绑定百万级的数据。
最后,最重要的特点之一就是熟悉的操作。FlexGrid基于Excel所有的交互行为,这可能是用户最常用的操作Grid的方式了。人们希望在滚动,点击,尤其是使用键盘命令(包括剪切板函数)时得到确定的行为,而不是我们自己发明的。我们模仿了Excel,因此用户在使用我们的表格时会感觉很舒畅,令人惊奇的是,许多其它的Grid发明了它们自己的行为或者不完全支持滚动和键盘行为。比如当你选择一行数据并按住向下箭头,许多表格并不会表现出你预想的行为。
使用标记语言来声明UI控件
现在,我们来看看在FlexGrid在AngularJS下的优势。在AngularJS下最大的好处就是FlexGrid的标记语言:Angular组件提供了使用标记语言来声明控件的能力。声明标记很好地遵循了MVVM设计模式,我们可以完全通过View(标记语言)来配置我们的组件。
FlexGrid支持使用Angular标记语言来声明完整的API。你完全可以使用标记语言设置属性,附加事件,配置子组件(比如列)。
下面是一个例子,演示了怎样使用Angular2标记语言来配置FlexGrid。
<wj-flex-grid [itemsSource]="data"> <wj-flex-grid-column [header]="'Country'" [binding]="'country'" [width]="'*'"></wj-flex-grid-column> <wj-flex-grid-column [header]="'Date'" [binding]="'date'"></wj-flex-grid-column> <wj-flex-grid-column [header]="'Revenue'" [binding]="'amount'" [format]="'n0'"></wj-flex-grid-column> <wj-flex-grid-column [header]="'Active'" [binding]="'active'"></wj-flex-grid-column> </wj-flex-grid>
下面是我们已声明的标记语言得到的结果。
许多其他的Grid组件仅提供了使用标记语言声明一个控件的能力,这导致所有的配置都必须使用JavaScript(ViewModel)完成。这使View和ViewMode之间混乱不清,迫使开发者必须使用JavaScript来改变控件UI。当这么做您将错失Angular 绑定的所有好处。我们认为这么做是一种反模式。看下面的不同:
<ag-grid-ng2 #agGrid // items bound to properties on the controller [gridOptions]="gridOptions" [columnDefs]="columnDefs"> </ag-grid-ng2>
通过使用完全支持标记语言的组件,你可以得到完全的MVVM模式支持,像其他开发平台(ASP.NET, Java, Silverlight, Flex)一样构建应用程序。
申明可复用的单元格类型模板
为了使用标记语言声明任何FlexGrid成员,我们也提供了单元格模板。单元格模板是为不同类型的单元格声明可复用模板的一种方式。单元格模板支持任何有效的Angular标记,包含绑定表达式,html和其他组件。单元格模板类型包括:标题单元格,编辑模式单元格,普通模式单元格等等。
通过单元格模板,FlexGrid提供了一个用于创建组件的表现方式。您不仅可以使用标记语言申明FlexGrid,还可以在每一个单元格中使用所有的Angular语法。让我们看看FlexGrid单元格模板标记是多么强大。
<wj-flex-grid [itemsSource]="data1" [allowSorting]="false" [deferResizing]="true"> <template wjFlexGridCellTemplate [cellType]="'TopLeft'" *ngIf="customTopLeft"> № </template> <template wjFlexGridCellTemplate [cellType]="'RowHeader'" *ngIf="customRowHeader" #cell="cell"> { {cell.row.index}} </template> <wj-flex-grid-column header="Country" binding="country"> <template wjFlexGridCellTemplate [cellType]="'Cell'" *ngIf="customCell" #item="item"> <img src="resources/{ {item.country}}.png" /> { {item.country}} </template> <template wjFlexGridCellTemplate [cellType]="'GroupHeader'" *ngIf="customGroupHeader" #item="item" #cell="cell"> <input type="checkbox" [(ngModel)]="cell.row.isCollapsed" /> { {item.name}} ({ {item.items.length}} items) </template> </wj-flex-grid-column> <wj-flex-grid-column header="Downloads" binding="downloads" [width]="170" [aggregate]="'Sum'"> <template wjFlexGridCellTemplate [cellType]="'ColumnHeader'" *ngIf="customColumnHeader"> <input type="checkbox" [(ngModel)]="uiCtx.highlightDownloads" /> Downloads </template> <template wjFlexGridCellTemplate [cellType]="'Cell'" *ngIf="customCell" #item="item"> <span [ngStyle]="{color: uiCtx.highlightDownloads? (item.downloads>10000 ?'green':'red'):''}"> { {item.downloads}} </span> </template> <template wjFlexGridCellTemplate [cellType]="'Group'" *ngIf="customGroup" #cell="cell"> Sum = { {cell.value | number:'1.0-0'}} </template> </wj-flex-grid-column> </wj-flex-grid>
我们声明的单元格模板得到的结果
Angular2中可复用的单元格模板
再次强调,为了在其他表格控件中实现这种效果,你需要编辑JavaScript文件,并ViewModel中编写。
使用数据绑定自动更新控件。