Grids

Ext.grid.Panel 是 Ext JS 中的一个核心组件. 表格是一个提供一个简单方式来显示、排序、分组和编辑数据的迷人组件.

基础表格面板

基础表格面板

我们从添加一个基础的 Ext.grid.Panel 表格面板来开始. 这是你所有的的需要知道的如何来建立一个简单的表格和运行它:

Model 和 Store

Ext.grid.Panel 是一个用来显示包含在 Ext.data.Store 里的数据的简单组件. Ext.data.Store 能被认为是一些记录的集合,或者一些 Ext.data.Model 的实例.

这种设置的好处是分离开我们的关注点. Ext.grid.Panel 只关心数据的展示,而 Ext.data.Store 使用 Ext.data.proxy.Proxy 来关注数据的查询和存储.

首先, 我们需要定义一个 Ext.data.Model 数据模型. 一个数据模型只是一系列用来表示数据类型的 fields(字段). 我们来定义一个表示 a “User”的数据模型:

Ext.define('User', {
    extend: 'Ext.data.Model',
    fields: [ 'name', 'email', 'phone' ]
});

然后我们来创建一个包含几个 “User” 实例的 Ext.data.Store(数据存储) .

var userStore = Ext.create('Ext.data.Store', {
    model: 'User',
    data: [
        { name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224' },
        { name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234' },
        { name: 'Homer', email: 'homer@simpsons.com', phone: '555-222-1244' },
        { name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254' }
    ]
});

为了简化操作,我们配置 Ext.data.Store 来加载内置数据. 在真正的应用程序中, 你极可能要配置 Ext.data.Store 来使用一个 Ext.data.proxy.Proxy 来从服务器加载数据.

表格面板

现在,我们有了一个model,定义了我们的数据结构. 我们也加载了几条 model 实例数据到了一个 Ext.data.Store 中了.我们准备好了使用 Ext.grid.Panel 来展现数据了.

在这个例子中,我们配置这个表格的 renderTo 方法来立即渲染这个表格到 HTML 文档中.

在很多情况下,表格是由 Ext.container.Viewport 派生出来的,这意味着渲染已经可以处理.

Ext.create('Ext.grid.Panel', {
    renderTo: document.body, 
    store: userStore,
    width: 400,
    height: 200,
    title: 'Application Users',
    columns: [
        {
            text: 'Name',
            width: 100,
            sortable: false,
            hideable: false,
            dataIndex: 'name'
        },
        {
            text: 'Email Address',
            width: 150,
            dataIndex: 'email',
            hidden: true
        },
        {
            text: 'Phone Number',
            flex: 1,
            dataIndex: 'phone'
        }
    ]
});

这就是所有的一切.

我们创建了一个来将它自己渲染到body元素中的 Ext.grid.Panel. 我们也告诉了这个表格面板从我们前面创建的 userStore 中来获取数据.

最后, 我们定义了表格面板的列并且指定了一个 dataIndex 属性. 这个 dataIndex 和我们model 中的一个字段相关联.

这个 “Name” 列有一个固定为 “100px” 的宽度并且禁止 sorting(排序)hiding(隐藏) . 这个 “Email Address” 列默认是隐藏的 (可以通过使用在其它列头上的菜单来再次显示). 最后, 这个 “Phone Number”flexes(伸缩) 来填充表格面板总宽度的余下部分.

查看一个更为复杂的例子, 参见 Array Grid Example.

表格渲染

你能使用列配置中的 renderer 属性来修改你要显示的数据的展现方式. renderer 是一个用来修改原始值的函数并返回一个新的值来显示.一些最常用的渲染方式包含在 Ext.util.Format中, 但你也能开发自己的格式:

columns: [
    {
        text: 'Birth Date',
        dataIndex: 'birthDate',
        // format the date using a renderer from the Ext.util.Format class
        renderer: Ext.util.Format.dateRenderer('m/d/Y')
    },
    {
        text: 'Email Address',
        dataIndex: 'email',
        // format the email address using a custom renderer
        renderer: function(value) {
            return Ext.String.format('<a href="mailto:{0}">{1}</a>', value, value);
        }
    }
]

查看 Kitchen Sink的 Array Grid 可以看一个使用了定制渲染的动态示例.

表格分组

将数据行分组来组织是很简单的.首先在我们的 store 中定义一个 groupField 属性:

Ext.create('Ext.data.Store', {
    model: 'Employee',
    data: ...,
    groupField: 'department'
});

然后, 我们在一个表格中配置可以处理分组显示数据的 Ext.grid.feature.Grouping特性:

Ext.create('Ext.grid.Panel', {
    ...
    features: [{ ftype: 'grouping' }]
});

查看 Kitchen Sink 的表格分组 表格面板 来看一个动态的示例.

选择模型

表格面板能简单的用于展示数据.然而通常需要与表格的数据进行交互.所有表格面板都有一个 Ext.selection.Model, 这个决定了将要选择使用哪个数据.选择数据模型有二种主要类型 Ext.selection.RowModel, 选择全部数据, 和 Ext.selection.CellModel, 选择独立的多个单元格.

表格面板默认使用 Ext.selection.RowModel , 但也很容易切换为使用 Ext.selection.CellModel:

Ext.create('Ext.grid.Panel', {
    selType: 'cellmodel',
    store: ...
});

使用Ext.selection.CellModel 时有很多变化. 首先,点击一个单元格现在只选择相应的单元格而不是整行.第二,键盘导航是从一个单元格到另一单元格而不是一行到另一行.基于单元格的选择model 通常与编辑结合使用.

编辑表格

表格面板内置支持编辑. 让我们看一下这两种主要编辑模式 - 行编辑和单元格编辑.

单元格编辑

Cell editing 允许你逐一编辑一个表格面板中的一个单元格的数据. 实现单元格编辑的第一个步骤是对可编辑的表格面板的每一个 Ext.grid.column.Column 进行配置.这个是通过使用Ext.grid.column.Column#editor 配置项来完成. 最简单的方法是指定你要使用一个编辑器的字段一个 xtype:

Ext.create('Ext.grid.Panel', {
    ...
    columns: [
        {
            text: 'Email Address',
            dataIndex: 'email',
            editor: 'textfield'
       }
    ]
});

如果需要控制更多编辑器的行为, Ext.grid.column.Column#editor 配置也可以对一个 Field 使用一个配置对象. 例如,如果我们用的是 Ext.form.field.Text 并且我们要必填:

columns: [
    text: 'Name',
    dataIndex: 'name',
    editor: {
        xtype: 'textfield',
        allowBlank: false
    }
[

你能使用在 “Ext.form.field.*” 包中的任意一个类作为一个编辑器的输入控件. 假定我们要编辑一个包含日期的列.我们能使用一个 Ext.form.field.Date 编辑器:

columns: [
    {
        text: 'Birth Date',
        dataIndex: 'birthDate',
        editor: 'datefield'
    }
]

Ext.grid.Panel 中的任意一个没有包含 Ext.grid.column.Column#editor 配置的 Ext.grid.column.Column 列将不可编辑.

现在我们配置了那些我们要编辑的列,并且编辑器的控件就会使用这些数据,下一个步骤是定义选择模型.让我们在 Ext.grid.Panel 配置中使用 Ext.selection.CellModel:

Ext.create('Ext.grid.Panel', {
    ...
    selType: 'cellmodel'
});

最后,为启用编辑我们要用 Ext.grid.plugin.CellEditing 来配置 Ext.grid.Panel:

Ext.create('Ext.grid.Panel', {
    ...
    selType: 'cellmodel',
    plugins: [{
        ptype: 'cellediting ',
        clicksToEdit: 1
    }]
});

这就是创建一个使用单元格编辑的可编辑表格要做的全部. 参见 单元格编辑 作为一个正常工作的例子.

行编辑

Row editing 使用你能一次编辑一个整行,而不是一个单元格一个单元的编辑. 行编辑与单元格编辑的方法几乎一样 - 我们所要做的只是修改插件类型为 Ext.grid.plugin.RowEditing 并且设置 selType 为 rowmodel.

Ext.create('Ext.grid.Panel', {
    ...
    selType: 'rowmodel',
    plugins: [{
        ptype: 'rowediting',
        clicksToEdit: 1
    }]
});

参见 行编辑 查看一个可以运行的例子.

表格分页

有时你的数据集太多而不能在一页中显示所有的数据. Ext.grid.Panel 通过使用 Ext.toolbar.Paging 来从数据集中分页显示,加载的页面将使用前一页/后一页按钮.

Store设置

在给一个Ext.grid.Panel设置分页前,我们必须配置 Ext.data.Store支持分页. 在下面的例子中我们给Ext.data.Store增加了 Ext.data.Store#pageSize 的设置 , 并且我们可以给 Ext.data.reader.Reader 配置一个 Ext.data.reader.Reader#totalProperty 属性:

Ext.create('Ext.data.Store', {
    model: 'User',
    autoLoad: true,
    pageSize: 4,
    proxy: {
        type: 'ajax',
        url : 'data/users.json',
        reader: {
            type: 'json',
            root: 'users',
            totalProperty: 'total'
        }
    }
});

Ext.data.reader.Reader#totalProperty 配置告诉 Ext.data.reader.Json从JSON响应的哪里来获得结果集的总行数.Ext.data.Store 配置成使用一个象下面这些数据一样的JSON返回数据:

{
    "success": true,
    "total": 12,
    "users": [
        { "name": "Lisa", "email": "lisa@simpsons.com", "phone": "555-111-1224" },
        { "name": "Bart", "email": "bart@simpsons.com", "phone": "555-222-1234" },
        { "name": "Homer", "email": "homer@simpsons.com", "phone": "555-222-1244" },
        { "name": "Marge", "email": "marge@simpsons.com", "phone": "555-222-1254" }
    ]
}

分页工具栏

我们已经设置 Ext.data.Store 支持分页, 剩下要配置的是 Ext.toolbar.Paging. 你可以在你应用布局的任意位置放置 Ext.toolbar.Paging ,但通常是停靠在 Ext.grid.Panel中:

Ext.create('Ext.grid.Panel', {
    store: userStore,
    columns: ...,
    dockedItems: [{
        xtype: 'pagingtoolbar',
        store: userStore,   // same store GridPanel is using
        dock: 'bottom',
        displayInfo: true
    }]
});

查看一个可正常工作的 Paging Grid 示例

缓冲渲染

作为使用分页工具栏来处理大数据结果集的一个替代方式是表格也支持缓冲渲染.你的用户可以滚动上千条记录而没有一次性将所有记录渲染到屏幕上的性能问题. 表格必须绑定一个定义好了pageSize的 Ext.data.BufferedStore组件.

只有足够的行被填充到表格的可见区域中和一个小ext.grid.panel-cfg-leadingbufferzone溢出到任一边用于允许滚动. 当滚动执行时,新的行就会按照滚动的方向渲染出来,而表格中那些相反方向的行就会被清除.

表格默认使用缓冲渲染,因此你不再需要在你的表格组件中增加插件.

查看一个可正常工作的 Buffered Renderer 示例.

Last updated