diff --git a/components/table/demo/ajax.md b/components/table/demo/ajax.md index c6ac0b8aa84b3481a4a74e6f968a1adb0ff1586a..66a7fa3c6b5877991d6e3bde8b022984eeb45ae9 100644 --- a/components/table/demo/ajax.md +++ b/components/table/demo/ajax.md @@ -1,15 +1,20 @@ -# 动态加载数据 +# 远程加载数据 - order: 7 -远程读取的表格是**更为常见的模式**,下面的表格使用了 `dataSource` 对象和远程数据源绑定和适配,并具有筛选、排序等功能以及页面 loading 效果。 +在 `0.11.0` 以后,`dataSource` 远程模式被移除,用户可以自行实现数据读取方式。 -**注意,此示例是静态数据模拟,数据并不准确,请打开网络面板查看请求。** +这个例子通过简单的 ajax 读取方式,演示了如何从服务端读取并展现数据,具有筛选、排序等功能以及页面 loading 效果。开发者可以自行接入其他数据处理方式。 + +另外,本例也展示了筛选排序功能如何交给服务端实现,列不需要指定具体的 `onFilter` 和 `sorter` 函数,而是在把筛选和排序的参数发到服务端来处理。 + +**注意,此示例是静态数据模拟,展示数据不会变化,请打开网络面板查看请求。** --- ````jsx -import { Table, Button } from 'antd'; +import { Table } from 'antd'; +import reqwest from 'reqwest'; const columns = [{ title: '姓名', @@ -30,23 +35,20 @@ const columns = [{ dataIndex: 'address' }]; -const dataSource = new Table.DataSource({ - url: '/components/table/demo/data.json', - resolve: function(result) { - return result.data; - }, - data: {}, - // 和后台接口返回的分页数据进行适配 - getPagination: function(result) { +const Test = React.createClass({ + getInitialState() { return { - total: result.totalCount, - pageSize: result.pageSize + data: [], + pagination: {}, + loading: false, }; }, - // 和后台接口接收的参数进行适配 - // 参数里提供了分页、筛选、排序的信息 - getParams: function(pagination, filters, sorter) { - console.log('getParams 的参数是:', pagination, filters, sorter); + handleTableChange(pagination, filters, sorter) { + const pager = this.state.pagination; + pager.current = pagination.current; + this.setState({ + pagination: pager + }); const params = { pageSize: pagination.pageSize, currentPage: pagination.current, @@ -56,61 +58,38 @@ const dataSource = new Table.DataSource({ for (let key in filters) { params[key] = filters[key]; } + this.fetch(params); + }, + fetch(params = {}) { console.log('请求参数:', params); - return params; - } -}); - -const Test = React.createClass({ - getInitialState() { - return { - dataSource: null, - pagination: { - onChange: this.hanlePageChange + this.setState({ loading: true }); + reqwest({ + url: 'demo/data.json', + method: 'get', + data: params, + type: 'json', + success: (result) => { + const pagination = this.state.pagination; + pagination.total = result.totalCount; + this.setState({ + loading: false, + data: result.data, + pagination, + }); } - }; - }, - hanlePageChange(page) { - // 使用受控属性 current,方便外部设置页数 - const pagination = this.state.pagination; - pagination.current = page; - this.setState({ - pagination, - dataSource: dataSource.clone(), }); }, - refresh() { - // 回到第一页 - const pagination = this.state.pagination; - pagination.current = 1; - this.setState({ - pagination, - dataSource: dataSource.clone(), - }); - }, - changeAndRefresh() { - // 回到第一页 - const pagination = this.state.pagination; - pagination.current = 1; - // 可以修改原来的 dataSource 再发请求 - this.setState({ - pagination, - dataSource: dataSource.clone({ - data: { city: 'hz' } - }), - }); + componentDidMount() { + this.fetch(); }, render() { - return
- - -   - - ; + return ( +
+ ); } }); diff --git a/components/table/demo/nopagination.md b/components/table/demo/nopagination.md index d681204215bab4271810b13d6ada9a8c31d5f541..f4b567c88ba181d7fcd19c806cd7a05b6fce0f60 100644 --- a/components/table/demo/nopagination.md +++ b/components/table/demo/nopagination.md @@ -2,7 +2,7 @@ - order: 8 -传入 pagination 为 false 即可。 +传入 pagination 为 false 即可。此时表格将完整显示 dataSource 内的数据,不进行任何分页。 --- diff --git a/components/table/demo/paging.md b/components/table/demo/paging.md index 76655dae2b0c0cf39a5092ffef25d3085af1c6f9..a6a92123be74e67ef4ac4372d8ecd0fe919140f7 100644 --- a/components/table/demo/paging.md +++ b/components/table/demo/paging.md @@ -35,7 +35,7 @@ for (let i = 0; i < 46; i++) { const pagination = { total: data.length, - current: 2, + current: 1, showSizeChanger: true }; diff --git a/components/table/index.jsx b/components/table/index.jsx index 4da74854d5240b06804e132cd2d4b94ce8d5be45..93131acff4a8a3483e70c81b4d210cac780ea2ad 100644 --- a/components/table/index.jsx +++ b/components/table/index.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import reqwest from 'reqwest'; import Table from 'rc-table'; import Checkbox from '../checkbox'; import Radio from '../radio'; @@ -13,49 +12,20 @@ import classNames from 'classnames'; function noop() { } -function defaultResolve(data) { - return data || []; -} - const defaultLocale = { filterTitle: '筛选', filterConfirm: '确定', filterReset: '重置' }; -class DataSource { - init(config) { - this.config = config; - this.url = config.url || ''; - this.resolve = config.resolve || defaultResolve; - this.getParams = config.getParams || noop; - this.getPagination = config.getPagination || noop; - this.headers = config.headers || {}; - this.data = config.data || {}; - } - - constructor(config) { - if (config) { - this.init(config); - } - } - - clone(config = {}) { - return new DataSource(objectAssign({}, this.config, config)); - } -} - let AntTable = React.createClass({ getInitialState() { return { // 减少状态 selectedRowKeys: [], - // only for remote - data: [], dataSource: this.props.dataSource, filters: {}, selectionDirty: false, - loading: this.props.loading, sortColumn: '', sortOrder: '', sorter: null, @@ -82,7 +52,7 @@ let AntTable = React.createClass({ }, propTypes: { - dataSource: React.PropTypes.oneOfType([React.PropTypes.array, React.PropTypes.instanceOf(DataSource)]) + dataSource: React.PropTypes.array, }, getDefaultSelection() { @@ -112,42 +82,23 @@ let AntTable = React.createClass({ nextProps.dataSource !== this.props.dataSource) { let selectedRowKeys = this.state.selectedRowKeys; // 把不在当前页的选中项去掉 - if (this.isLocalDataSource()) { - let currentPageRowKeys = - this.getLocalDataPaging(nextProps.dataSource).map( - (record, i) => this.getRecordKey(record, i) - ); - selectedRowKeys = selectedRowKeys.filter((key) => { - return currentPageRowKeys.indexOf(key) >= 0; - }); - } + let currentPageRowKeys = + this.getCurrentPageData(nextProps.dataSource).map( + (record, i) => this.getRecordKey(record, i) + ); + selectedRowKeys = selectedRowKeys.filter((key) => { + return currentPageRowKeys.indexOf(key) >= 0; + }); this.setState({ selectionDirty: false, selectedRowKeys, dataSource: nextProps.dataSource, - loading: true - }, this.fetch); - } - if ('loading' in nextProps) { - this.setState({ - loading: nextProps.loading }); } }, hasPagination(pagination) { - if (pagination === undefined) { - pagination = this.props.pagination; - } - return pagination !== false; - }, - - isLocalDataSource() { - return Array.isArray(this.state.dataSource); - }, - - getRemoteDataSource() { - return this.state.dataSource; + return this.props.pagination !== false; }, toggleSortOrder(order, column) { @@ -167,7 +118,7 @@ let AntTable = React.createClass({ sortOrder = order; } } - if (this.isLocalDataSource()) { + if (typeof column.sorter === 'function') { sorter = function () { let result = column.sorter.apply(this, arguments); if (sortOrder === 'ascend') { @@ -182,7 +133,7 @@ let AntTable = React.createClass({ sortColumn, sorter }; - this.fetch(newState); + this.setState(newState); this.props.onChange.apply(this, this.prepareParamsArguments(objectAssign({}, this.state, newState))); }, @@ -202,7 +153,7 @@ let AntTable = React.createClass({ selectionDirty: false, filters }; - this.fetch(newState); + this.setState(newState); this.props.onChange.apply(this, this.prepareParamsArguments(objectAssign({}, this.state, newState))); }, @@ -293,7 +244,7 @@ let AntTable = React.createClass({ selectionDirty: false, pagination }; - this.fetch(newState); + this.setState(newState); this.props.onChange.apply(this, this.prepareParamsArguments(objectAssign({}, this.state, newState))); }, @@ -391,10 +342,6 @@ let AntTable = React.createClass({ return columns; }, - getCurrentPageData() { - return this.isLocalDataSource() ? this.getLocalDataPaging() : this.state.data; - }, - getColumnKey(column, index) { return column.key || column.dataIndex || index; }, @@ -458,7 +405,7 @@ let AntTable = React.createClass({ let pagination = objectAssign(this.state.pagination, { pageSize: pageSize }); - this.fetch({pagination}); + this.setState({ pagination }); }, renderPagination() { @@ -470,16 +417,14 @@ let AntTable = React.createClass({ 'ant-table-pagination': true, 'mini': this.props.size === 'middle' || this.props.size === 'small', }); - let total = this.state.pagination.total; - if (!total && this.isLocalDataSource()) { - total = this.getLocalData().length; - } - return (total > 0) ? : null; + let total = this.state.pagination.total || this.getLocalData().length; + return (total > 0) ? + : null; }, prepareParamsArguments(state) { @@ -496,61 +441,13 @@ let AntTable = React.createClass({ return [pagination, filters, sorter]; }, - fetch(newState) { - if (this.isLocalDataSource()) { - if (newState) { - this.setState(newState); - } - } else { - // remote 模式使用 this.dataSource - let dataSource = this.getRemoteDataSource(); - if (!dataSource) { - return null; - } - let state = objectAssign({}, this.state, newState); - if (newState || !this.state.loading) { - this.setState(objectAssign({ - loading: true - }, newState)); - } - let buildInParams = dataSource.getParams.apply(this, this.prepareParamsArguments(state)) || {}; - return reqwest({ - url: dataSource.url, - method: 'get', - data: objectAssign(buildInParams, dataSource.data), - headers: dataSource.headers, - type: 'json', - success: (result) => { - if (this.isMounted()) { - let pagination = objectAssign( - state.pagination, - dataSource.getPagination.call(this, result) - ); - this.setState({ - selectionDirty: false, - loading: false, - data: dataSource.resolve.call(this, result), - pagination: pagination - }); - } - }, - error: () => { - this.setState({ - loading: false, - data: [] - }); - } - }); - } - }, - findColumn(myKey) { return this.props.columns.filter((c) => { return this.getColumnKey(c) === myKey; })[0]; }, - getLocalDataPaging(dataSource) { + getCurrentPageData(dataSource) { let data = this.getLocalData(dataSource); let current, pageSize; let state = this.state; @@ -595,22 +492,14 @@ let AntTable = React.createClass({ if (values.length === 0) { return; } - data = data.filter((record) => { - return values.some((v)=> { - return col.onFilter(v, record); - }); - }); + data = col.onFilter ? data.filter(record => { + return values.some(v => col.onFilter(v, record)); + }) : data; }); } return data; }, - componentDidMount() { - if (!this.isLocalDataSource()) { - this.fetch(); - } - }, - render() { let data = this.getCurrentPageData(); let columns = this.renderRowSelection(); @@ -644,7 +533,7 @@ let AntTable = React.createClass({ expandIconAsCell={expandIconAsCell} /> {emptyText} ; - if (this.state.loading) { + if (this.props.loading) { // if there is no pagination or no data, the height of spin should decrease by half of pagination let paginationPatchClass = (this.hasPagination() && data && data.length !== 0) ? 'ant-table-with-pagination' @@ -661,6 +550,4 @@ let AntTable = React.createClass({ } }); -AntTable.DataSource = DataSource; - export default AntTable; diff --git a/components/table/index.md b/components/table/index.md index 468c7b9d90931a3627915776aea63de7c6e34d1c..b5759ece03e26a22279f54e397a61d83b134d597 100644 --- a/components/table/index.md +++ b/components/table/index.md @@ -16,14 +16,10 @@ ## 如何使用 -Table 有两种模式,本地数据和远程数据模式。 - -**本地数据模式**是指数据一次性载入内存,纯前端进行分页、筛选、排序等功能。 - -通过指定表格的数据源 `dataSource` 为一个数据数组。 +指定表格的数据源 `dataSource` 为一个数组。 ```jsx -var dataSource = [{ +const dataSource = [{ key: '1', name: '胡彦斌', age: 32, @@ -35,28 +31,22 @@ var dataSource = [{ address: '西湖区湖底公园1号' }]; -
-``` - -**远程数据模式**是更常见的业务场景,是一次只从服务端读取一页的数据放在前端,执行筛选、排序、切换页码等操作时均向后台发送请求,后台返回当页的数据和相关分页信息。 - -> 远程数据模式后续可能删除,目前不推荐使用。 - -通过指定表格的数据源 `dataSource` 为一个 DataSource 的实例如下。 +const columns = [{ + title: '姓名', + dataIndex: 'name' +}, { + title: '年龄', + dataIndex: 'age' +}, { + title: '住址', + dataIndex: 'address' +}]; -```jsx -var dataSource = new Table.DataSource({ - url: '/api/users', - resolve: function(result) { - return result.data; - }, - getPagination: function(result) {}, - getParams: function(pagination, filters, sorter) {} -}); - -
+
``` +> 注:`dataSource` 在 `0.11.0` 版本后不再支持远程模式。 + ## API ### Table @@ -66,7 +56,7 @@ var dataSource = new Table.DataSource({ | rowSelection | 列表项是否可选择 | Object | | false | | pagination | 分页器 | Object | 配置项参考 [pagination](/components/pagination),设为 false 时不显示分页 | | | size | 正常或迷你类型 | String | `default` or `small`| default | -| dataSource | 数据源,可以为数组(本地模式)或一个数据源描述对象(远程模式) | Array or Object | | | +| dataSource | 数据数组 | Array | | | | columns | 表格列的配置描述,具体项见下表 | Array | | 无 | | rowKey | 表格列 key 的取值 | Function(recode, index):string | | record.key | | expandIconAsCell | 设置展开 Icon 是否单独一列 | Boolean | | true | @@ -88,21 +78,10 @@ var dataSource = new Table.DataSource({ | filters | 表头的筛选菜单项 | Array | | | | onFilter | 本地模式下,确定筛选的运行函数 | Function | | | | filterMultiple | 是否多选 | Boolean | | true | -| sorter | 排序函数,本地模式下为一个函数,远程模式下为布尔值 | Function or Boolean | | 无 | +| sorter | 排序函数,本地排序使用一个函数,需要服务端排序可设为 true | Function or Boolean | | 无 | | width | 列宽度 | String or Number | | 无 | | className | 列的 className | String | | 无 | -### dataSource - -远程数据源配置对象。 - -| 参数 | 说明 | 类型 | 可选值 | 默认值 | -|---------------|--------------------------|-----------------|---------------------|---------| -| url | 数据源地址 | String | | | -| resolve | 获得数据的解析函数,接收参数为远程数据返回的 result | Function | | | -| getPagination | 和后台接口返回的分页数据进行适配的函数,返回值会传给表格中的分页器 | Function | | | -| getParams | 和后台接口接收的参数进行适配,返回值会作为请求的参数发送 | Function | | 无 | - ## 注意 按照 React 的[规范](http://facebook.github.io/react/docs/multiple-components.html#dynamic-children),所有的组件数组必须绑定 key。在 Table 中,默认将每列数据的 `key` 属性作为唯一的标识。 diff --git a/package.json b/package.json index d4644bd8fcbdfdad36787703e7cd9d9df70ea8ea..4354dcba6364ddb1d921db7ce74d2e9e1231b8fb 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "rc-upload": "~1.7.0", "rc-util": "~3.0.1", "react-slick": "~0.9.1", - "reqwest": "~2.0.5", "semver": "~5.0.3", "util-deprecate": "~1.0.1", "velocity-animate": "~1.2.2", @@ -106,6 +105,7 @@ "react-dom": "~0.14.2", "react-router": "~1.0.0", "react-stateless-wrapper": "~1.0.2", + "reqwest": "~2.0.5", "webpack": "^1.10.1", "webpack-babel-jest": "^1.0.0", "webpack-dev-middleware": "^1.2.0" diff --git a/scripts/demo.js b/scripts/demo.js index fc03b4101420e57ddbd420203c1e6fd213cdd63f..7c38cc49a01a46ce2f633713619cb49fdc5f73f4 100644 --- a/scripts/demo.js +++ b/scripts/demo.js @@ -32,6 +32,7 @@ window.React = React; window.ReactDOM = ReactDOM; window['object-assign'] = require('object-assign'); window['classnames'] = require('classnames'); +window['reqwest'] = require('reqwest'); require('./importCss'); antd.Datepicker.locale = {