入门
MultiRow 控件扩展了常规的表单布局,使用多行来表示每个数据项。(它应该有一个更加准确的名字‘MultiRowPerRecordGrid’,但是实在太长了)。
MultiRow 控件允许用户以表格形式查看和编辑数据,就像普通的表单一样。不同的是。MultiRow 允许您绑定一个数据项到多行上,以创建类似表单的界面,使用最小的水平滚动条展示很大量的列。
MultiRow 控件继承自FlexGrid 控件,如果会使用FlexGrid ,那么您一定可以使用MultiRow 。
主要新增的属性为layoutDefinition ,它接受一个描述表单行和单元格布局的对象。
MultiRow 控件不只是常规表单的简单替代,在一些场景中,它非常适用。
为了在您的应用程序中使用MultiRow 控件,需要添加对wijmo , wijmo.grid ,和wijmo.grid.multirow 模块的引用。然后通过在页面中添加宿主元素或者AngularJs的wj-multi-row 指令来实例化MultiRow 。
<!DOCTYPE html>
<html>
<head>
<link href="styles/vendor/wijmo.css" rel="stylesheet" />
<script src="scripts/vendor/wijmo.min.js"></script>
<script src="scripts/vendor/wijmo.grid.min.js"></script>
<script src="scripts/vendor/wijmo.grid.multirow.min.js"></script>
<head>
<body>
<!-- using AngularJS -->
<wj-multi-row items-source="data" layout-definition="layoutDef">
</wj-multi-row>
<!-- using pure JS -->
<div id="multirow"></div>
</body>
</html>
onload = function() {
// create and initialize the MultiRow using pure JavaScript
var theMultiRow = new wijmo.grid.multirow.MultiRow('#multirow', {
itemsSource: getData(),
columnLayout: getColumnLayout()
});
}
多行布局定义
MultiRow 控件使用多行来展示每一条记录。记录布局通过layoutDefinition 属性定义。
layoutDefinition 包含了cell group对象数组。cell group对象拥有以下属性:
header : 组名
colspan : 一个组中跨列的数量
cells : 一个由代表组中单元格的对象组成的数组,该单元格是包含一个额外的colspan 属性的列.
下面的例子说明了layoutDefiniton 属性的用法:
现在,让我们来使用MultiRow 不同的布局来展示相同的数据。使用combo box 去选择一种布局和表单的数据分组方式。
注意,MultiRow 控件提供所有的通用表单特点,包含编辑,排序,过滤和列宽:
<wj-multi-row
items-source="orders"
layout-definition="layoutDefs.currentItem.def">
</wj-multi-row>
<wj-combo-box
items-source="layoutDefs"
display-member-path="name"
selected-index-changed="layoutDefChanged(s,e)">
</wj-combo-box>
<p>
{{layoutDefs.currentItem.description}}</p>
// 例子的布局定义
$scope.layoutDefs = new wijmo.collections.CollectionView([
{
name: 'Traditional',
description: 'Traditional grid view, with one row per record. The user must scroll horizontally to see the whole record.',
def: [
{ cells: [{ binding: 'id', header:'ID' }]},
{ cells: [{ binding: 'date', header:'Ordered' }]},
{ cells: [{ binding: 'shippedDate', header:'Shipped' }]},
// ... 每列一组 ...
]
},
{
name: 'Compact',
description: 'This view uses two rows per record. The layout is divided into three column groups: order, customer, and shipper',
def: [
{
header: 'Order', colspan: 2, cells: [
{ binding: 'id', header: 'ID' },
{ binding: 'date', header: 'Ordered' },
{ binding: 'amount', header: 'Amount' },
{ binding: 'shippedDate', header: 'Shipped' }
]
},
// ... 两个小组,为客户和托运人 ...
]
},
{
name: 'Detailed',
description: 'This view uses three rows per record. The layout is divided into three column groups: order, customer, and shipper',
def: [
{
header: 'Order', colspan: 2, cells: [
{ binding: 'id', header: 'ID', colspan: 2 },
{ binding: 'amount', header: 'Amount', colspan: 2 },
{ binding: 'date', header: 'Ordered' },
{ binding: 'shippedDate', header: 'Shipped' }
]
},
// ... 两个小组,为客户和托运人 ...
]
}
]);
Result (live):
{{layoutDefs.currentItem.description}}
layoutDefinition 属性定义了单元格的布局方式。它包含由单元格组对象组成的数组。每个单元格组定义组的跨列数和组成每一个组的单元格。
下面的图说明了一个单元格组的解释方式和怎样转化为网格布局。
上面组包含三个列,共包含6个具有不同跨度的单元格。当生成网格布局时,表单在一行尽可能适应多的单元格。当跨列数满时,折叠到下一行。每一行的最后一个单元格将会自动伸展用来适应组的 colspan 。 这个过程与折行创建新的段落很相似。
layoutDefinition 对象中的多个组的也会应用相同的处理过程。
可折叠的列标题
默认情况下, MultiRow 控件会创建跨行的列标题并且为每一个 layoutDefinition 定义的单元格展示列标题。
那些特定单元格的列标题将会用来排序或者过滤数据,就像常规表单一样。
在某些情况下,你可能想将列标题折叠为一行,只展示组名而不是每一个列标题。这将会节省单元格列标题占用的空间。为了折叠列标题,设置collapsedHeaders 属性为真。 在那些场景下,记住在组上设置header 属性,因此列标题将不为空。
记录,组和单元格样式
在大多数的应用中,你可能想展示每一个条记录和每一个分组的起始位置与结束位置。MultiRow 控件通过向每组第一和最后的行列的单元格元素添加类样式来实现。这些类名分别是 wj-record-start
, wj-record-end
, wj-group-start
,
和 wj-group-end
.
下面的列子展示了如何使用那些CSS类样式来定制记录和分组分隔符的外观,它展示了如何使用标准的cssClass 属性
来定制组中指定单元格的外观。
<wj-multi-row
class="multirow-css"
items-source="orders"
layout-definition="ldThreeLines">
</wj-multi-row>
/* custom styling for a MultiRow */
.multirow-css .wj-cell.wj-record-end:not(.wj-header) {
border-bottom-color: #8fabff; /* blue lines between records */
}
.multirow-css .wj-cell.wj-group-end {
border-right-color: #bc5505; /* brown lines between groups */
}
.multirow-css .wj-cell.id {
color: #c0c0c0;
}
.multirow-css .wj-cell.amount {
color: #014701;
font-weight: bold;
}
.multirow-css .wj-cell.email {
color: #0010c0;
text-decoration: underline;
}
Result (live):
分组
MultiRow 控件支持CollectionView -based 分组,就像标准的FlexGrid 。为了使用分组,需要根据原始数据来创建一个CollectionView ,并且添加一个或多个 GroupDescription 对象到集合的 GroupDescriptions 数组。
<wj-multi-row
items-source="groupedOrders"
layout-definition="ldThreeLines"
group-header-format="City: <b>{value} </b>({count:n0} items)"
control="groupingGrid">
</wj-multi-row>
<label>
<input type="checkbox" ng-model="groupingGrid.showGroups">
Show Groups
</label>
<br />
<button class="btn" ng-click="groupingGrid.collapseGroupsToLevel(0)">
Collapse All
</button>
<button class="btn" ng-click="groupingGrid.collapseGroupsToLevel(10)">
Expand All
</button>
// expose grouped orders to the controller
$scope.groupedOrders = new wijmo.collections.CollectionView(orders, {
groupDescriptions: [
'customer.city',
],
newItemCreator: function () {
return { // add empty customer and shipper objects to new orders
customer: {},
shipper: {}
}
},
});
Result (live):
Show Groups
Collapse All
Expand All
过滤
The MultiRow 控件支持过滤,就像标准的FlexGrid 控件。
过滤功能是 wijmo.grid.filter.FlexGridFilter 类来提供。为了向MultiRow 控件添加一个过滤界面,需要创建一个 FlexGridFilter 控件,并且将 MultiRow 作为一个参数传递到构造函数中。
如果你想使用AngularJs,你也需要通过指令wj-flex-grid-filter 添加一个过滤器到表单中,它作为表单指令的子指令。
<wj-multi-row
items-source="orders"
layout-definition="ldThreeLines"
initialized="initFlexFilter(s, e)">
</wj-multi-row>
// add a filter to the MultiRow
$scope.initFlexFilter = function (s, e) {
var filter = new wijmo.grid.filter.FlexGridFilter(s);
}
Result (live):
冻结行和列
MultiRow 允许您冻结行和列,它们将在用户滚动表单的过程中保持位置不变。被冻结的单元格可以被编辑和选择,与Excel和FlexGrid控件中的表现完全一样。
下面的例子允许你切换是否行和列的第一组被冻结。
<wj-multi-row
items-source="orders"
layout-definition="ldTwoLines"
control="frozenGrid">
</wj-multi-row>
<button
class="btn btn-default"
ng-click="toggleFreeze(2, 2)">
{{ frozenGrid.frozenRows == 0 ? 'Freeze' : 'Unfreeze' }}
</button>
// toggle frozen rows/columns
$scope.toggleFreeze = function (rows, cols) {
var flex = $scope.frozenGrid;
if (flex) {
flex.frozenColumns = flex.frozenColumns ? 0 : cols;
flex.frozenRows = flex.frozenRows ? 0 : rows;
}
}
/* custom styling for frozen cells */
.wj-cell.wj-frozen:not(.wj-header):not(.wj-group):not(.wj-state-selected):not(.wj-state-multi-selected) {
background-color: #f3fbcc;
}
Result (live):
{{ frozenGrid.frozenRows == 0 ? 'Freeze' : 'Unfreeze' }}
分页
MultiRow 支持通过 IPagedCollectionView 接口进行分页,该接口与.NET 中一个接口非常相似。
为了进行分页,需要设置 IPagedCollectionView.pageSize 属性为一页中项的数量,并提供一个导航栏UI。
在下面的例子中,我们使用JavaScript在一页中展示4项。 我们添加导航按钮并且在按钮点击指令中调用IPagedCollectionView 方法。 我们使用pageIndex 和 pageCount 属性去展示当前的页面和总页数。
<wj-multi-row
items-source="pagedOrders"
layout-definition="ldThreeLines">
</wj-multi-row>
<div class="btn-group">
<button type="button" class="btn" ng-click="pagedOrders.moveToFirstPage()">
<span class="glyphicon glyphicon-fast-backward"></span>
</button>
<button type="button" class="btn" ng-click="pagedOrders.moveToPreviousPage()">
<span class="glyphicon glyphicon-step-backward"></span>
</button>
<button type="button" class="btn" disabled style="width:100px">
{{pagedOrders.pageIndex + 1 | number}} / {{pagedOrders.pageCount | number}}
</button>
<button type="button" class="btn" ng-click="pagedOrders.moveToNextPage()">
<span class="glyphicon glyphicon-step-forward"></span>
</button>
<button type="button" class="btn" ng-click="pagedOrders.moveToLastPage()">
<span class="glyphicon glyphicon-fast-forward"></span>
</button>
</div>
// expose paged orders to the controller
$scope.pagedOrders = new wijmo.collections.CollectionView(orders, {
pageSize: 4
});
Result (live):
{{pagedOrders.pageIndex + 1 | number}} / {{pagedOrders.pageCount | number}}
添加和移除记录
MultiRow 控件支持 FlexGrid 控件提供的 allowAddNew 和 allowDelete 属性。
设置 allowAddNew 属性为真将会导致在表单底部展示 '新行模板' 行的集合。当用户在一个新的行模板中开始编辑一个单元格,一个新项将会添加到数据源集合。 当用户结束编辑新项(通过移除选中或者焦点),这个新项就会被提交。
设置allowDelete 属性为真将会导致表单监控键盘事件,当一整行被选中并且用户点击了‘Delete’键时,那么这行就会被删除。