提交 62d4bbd5 编写于 作者: A afc163

remove remote dataSource

上级 91387c2f
# 动态加载数据
# 远程加载数据
- 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 <div>
<Table columns={columns} dataSource={this.state.dataSource} pagination={this.state.pagination} />
<Button type="primary" onClick={this.refresh}>
加载初始数据
</Button>
&nbsp;
<Button onClick={this.changeAndRefresh}>
加载 city=hz 的数据
</Button>
</div>;
return (
<Table columns={columns}
dataSource={this.state.data}
pagination={this.state.pagination}
loading={this.state.loading}
onChange={this.handleTableChange} />
);
}
});
......
......@@ -2,7 +2,7 @@
- order: 8
传入 pagination 为 false 即可。
传入 pagination 为 false 即可。此时表格将完整显示 dataSource 内的数据,不进行任何分页。
---
......
......@@ -35,7 +35,7 @@ for (let i = 0; i < 46; i++) {
const pagination = {
total: data.length,
current: 2,
current: 1,
showSizeChanger: true
};
......
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) ? <Pagination className={classString}
onChange={this.handlePageChange}
total={total}
pageSize={10}
onShowSizeChange={this.handleShowSizeChange}
{...this.state.pagination} /> : null;
let total = this.state.pagination.total || this.getLocalData().length;
return (total > 0) ?
<Pagination className={classString}
onChange={this.handlePageChange}
total={total}
pageSize={10}
onShowSizeChange={this.handleShowSizeChange}
{...this.state.pagination} /> : 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}
</div>;
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;
......@@ -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号'
}];
<Table dataSource={dataSource} />
```
**远程数据模式**是更常见的业务场景,是一次只从服务端读取一页的数据放在前端,执行筛选、排序、切换页码等操作时均向后台发送请求,后台返回当页的数据和相关分页信息。
> 远程数据模式后续可能删除,目前不推荐使用。
通过指定表格的数据源 `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) {}
});
<Table dataSource={dataSource} />
<Table dataSource={dataSource} columns={columns} />
```
> 注:`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` 属性作为唯一的标识。
......
......@@ -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 = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册