如果您立即需要,您可以尝试使用分支 v0.11 中的表格并创建自己的列标题并使用单击/点击事件来确定如何对表格行进行排序(升序/降序)。 我有点flux/reflux/redux,想看看MUI之外的排序逻辑。 提供列标题排序指示器并公开这些事件的回调应该不难。 如果您有时间,我们很乐意接受 PR(针对分支 v0.11)。
有人在做这个吗? 我们的团队(@VladimirPal)很乐意尝试使用@jkruder的方法。
我认为我们只需要sortIndicator
和onClick
为TableHeaderColumn
, sortIndicator
可以是用户传入的任何组件(通常是FontIcon
)。排序逻辑将在Table
之外处理。
排序逻辑可以很复杂,例如单列排序、多列排序、排序周期的顺序( Asc->Desc->None
或Desc->Asc
),以及多列排序中的列优先级。 也许最好保持 MUI 的Table
精简并将逻辑移出。 你的想法? @jkruder @sjstebbins
@zachguo绝对同意将排序逻辑保留在表格之外。 我会考虑['asc', 'desc', 'none']
的默认排序数组,每次单击列标题都会使索引返回 0,并使用排序值和列名/编号/标识符调用 CB。 该数组可以作为自定义值的道具提供。
多列排序可以由表的消费者处理。 我已经看到点击列的顺序优先。 可以由消费者维护为对象数组: [{columnId: 'asc'}, {otherColumnId: 'desc'}]
。 我会添加一个 multiColumnSortable(随意更改名称)字段来控制多列排序。
@jkruder TBH 我不确定将排序数组保存到Table
是否是个好主意。 我正在考虑一种较低级别的方法,通过使indicator
和onClick
与排序逻辑解耦,这样
Table
组件将纯粹用于渲染(因此更容易推理),但缺点是 API 对于普通用户来说不是很方便。
@zachguo关于指标的好点; 所有关于解耦 UI。 我们可以按照您的建议进行操作,并使用indicator
和onClick
创建一个无意见版本的表格,然后在文档中创建一个可排序的表格来演示 API。 最坏的情况是,如果我们发现用户没有找到直观的 API,我们可以提供一个SortableTable
组件。
是的, SortableTable
是个好主意。
我们将使用icon
代替indicator
,如在 MD 的 DataTable 规范中所示:
@zachguo这是什么状态?
@VladimirPal开发了一种支持排序和分页的软件,无需更改单行 MUI 代码。 当我们认为它准备好时,我们将对其进行测试并将其移植到这里。
我很想看到这个,刚刚升级到 0.11 来玩桌子
干得好
@zachguo打算自己开始构建一个可排序的、可分页的表,但看到你有一些工作。 你觉得什么时候去比较好? 与此同时,很高兴在 material-ui 主干之外使用一些东西。
@zachguo @VladimirPal有关此状态的任何更新?
@shaurya947 @daniel-sim @sjstebbins
我们在服务器端和客户端都进行了排序(单列和多列排序)和分页,但发现很难将这些新功能重构为易于使用的 API,同时又不失 MUI 目前的可组合性已。
实际上可以通过组合MUI的表格组件来实现排序和分页,而无需编写太多代码。 总体思路是自己跟踪当前数据/排序/页面,让 MUI 的表格组件纯粹渲染它们。
恕我直言,与其提供排序和分页等高级 API,不如保留当前的低级 API。 更少的开销,更容易组合。 但是,为了使渲染排序和分页更容易,我们可以添加一个icon
/ indicator
属性和一个onClick
事件到TableHeaderColumn
,甚至是一个新的pre - 样式的TableFooter
组件。
你的意见?
抄送: @oliviertassinari
@zachguo :
实际上可以通过组合MUI的表格组件来实现排序和分页,而无需编写太多代码。 总体思路是自己跟踪当前数据/排序/页面,让 MUI 的表格组件纯粹渲染它们。
是的,这是完全可行的。
您提到的道具是相当通用的,除了排序之外,也可以在其他场景中派上用场。 所以请随意为此写一个 PR..
这可能并不理想,但我能够通过在 TableHeaderColumn 中包含一个带有 onClick 的 div 来实现排序。 修复 TableHeaderColumn 的 onClick 行为会很棒,而且 IMO 完全可以满足 99% 的情况。
@roieki这也是我们所做的
@shaurya947 @jkruder实际上有 $ TableHeaderColumn
的onClick
道具,但它不起作用。 相关#2011
有人愿意接受吗?
类似的东西
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn, TableFooter } from 'material-ui/Table';
import { SmartTableRow } from 'components';
import React, { PropTypes, Component } from 'react';
import styles from './SmartTable.scss';
import SortIcon from 'material-ui/svg-icons/action/swap-vert';
import IconButton from 'material-ui/IconButton';
import ChevronLeft from 'material-ui/svg-icons/navigation/chevron-left';
import ChevronRight from 'material-ui/svg-icons/navigation/chevron-right';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
function sortFunc(a, b, key) {
if (typeof(a[key]) === 'number') {
return a[key] - b[key];
}
const ax = [];
const bx = [];
a[key].replace(/(\d+)|(\D+)/g, (_, $1, $2) => { ax.push([$1 || Infinity, $2 || '']); });
b[key].replace(/(\d+)|(\D+)/g, (_, $1, $2) => { bx.push([$1 || Infinity, $2 || '']); });
while (ax.length && bx.length) {
const an = ax.shift();
const bn = bx.shift();
const nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
if (nn) return nn;
}
return ax.length - bx.length;
}
class SmartTable extends Component {
static childContextTypes = {
muiTheme: React.PropTypes.object.isRequired
}
constructor(props, context) {
super(props, context);
this.state = { isAsc: false, sortHeader: null };
}
getChildContext() {
return { muiTheme: getMuiTheme() };
}
sortByColumn(column, data) {
const isAsc = this.state.sortHeader === column ? !this.state.isAsc : true;
const sortedData = data.sort((a, b) => sortFunc(a, b, column));
if (!isAsc) {
sortedData.reverse();
}
this.setState({
data: sortedData,
sortHeader: column,
isAsc
});
}
render() {
const { offset, limit, total, tableHeaders, data, onPageClick } = this.props;
return (
<Table className={ styles.table } selectable={false}>
<TableHeader displaySelectAll ={false} adjustForCheckbox={false}>
<TableRow>
{!!tableHeaders && tableHeaders.map((header, index) => (
<TableHeaderColumn key={index}>
<div className={styles.rowAlign}>
{header.alias}
<SortIcon
id={header.dataAlias}
className={styles.sortIcon}
onMouseUp={(e) => this.sortByColumn(e.target.id, data) }
/>
</div>
</TableHeaderColumn>
))}
</TableRow>
</TableHeader>
<TableBody showRowHover stripedRows displayRowCheckbox={false}>
{!!data && data.map((row, index) => (
<SmartTableRow key={index} {...{ row, index, tableHeaders }} />
))}
</TableBody>
<TableFooter>
<TableRow>
<TableRowColumn>
<div className={styles.footerControls}>
{ `${Math.min((offset + 1), total)} - ${Math.min((offset + limit), total)} of ${total}` }
<IconButton disabled={offset === 0} onClick={onPageClick.bind(null, offset - limit)}>
<ChevronLeft/>
</IconButton>
<IconButton disabled={offset + limit >= total} onClick={onPageClick.bind(null, offset + limit)}>
<ChevronRight/>
</IconButton>
</div>
</TableRowColumn>
</TableRow>
</TableFooter>
</Table>
);
}
}
SmartTable.propTypes = {
tableHeaders: PropTypes.array,
data: PropTypes.array,
offset: PropTypes.number, // current offset
total: PropTypes.number, // total number of rows
limit: PropTypes.number, // num of rows in each page
onPageClick: PropTypes.func // what to do after clicking page number
};
export default SmartTable;
.table {
width: auto;
padding-top: 30px;
}
.rowAlign {
display: flex;
align-items: center;
}
.footerControls {
display: flex;
align-items: center;
justify-content: flex-end;
}
.sortIcon {
cursor: pointer;
path {
fill: rgb(158, 158, 158) !important;
pointer-events: none;
}
}
@vorlov很好的例子,谢谢。 您也可以发布您的SmartTableRow
组件吗?
@chrisrittelmeyer当然,还更新了上表的代码
import { TableRow, TableRowColumn } from 'material-ui/Table';
import React, { PropTypes } from 'react';
import formatTableCell from './formatTableCell';
const SmartTableRow = ({ index, row, tableHeaders }) => (
<TableRow key={index}>
{tableHeaders.map((header, propIndex) => (
<TableRowColumn key={propIndex}>{formatTableCell(row[header.dataAlias], header.format)}</TableRowColumn>
))}
</TableRow>
);
SmartTableRow.propTypes = {
index: PropTypes.number,
row: PropTypes.object
};
export default SmartTableRow;
@vorlov你有这个代码并且可以在任何地方工作吗?
@chrisrittelmeyer stange 问题)当然我有)
哦! 我应该更具体一点 - 您是否在可以将我们链接到的环境中拥有它? 上面的代码仍然缺少一些依赖项,因此与其在此处粘贴所有部分,不如将我指向一个 repo 可能更容易。
@vorlov这是智能表的一个非常好的实现,但是我不太了解分页。 我没有看到任何逻辑来处理渲染之前的偏移量、限制和总计?
@JK82由你决定,我没有在我的项目中使用分页,添加它以供将来实施。
它可以在 componentWillReceiveProps 或 componentWillMount 中完成
@vorlov Sweet,这又是一个非常好的工作
@vorlov嗯,这种方法通过引用直接影响道具(redux 存储):\
@NeXTs你是什么意思?
@vorlov
const sortedData = data.sort((a, b) => sortFunc(a, b, column));
data.sort
- sort 是mutator所以它修改data
直接引用this.props.data
$ 的字段,不是吗?
这样做的原因是什么?
this.setState({
data: sortedData
})
如果render
不使用来自 state 的数据,它只使用const { data } = this.props;
也许想法是从道具中获取data
,克隆它,将其存储在 state 中,然后在 state 中排序/恢复data
?
TableSortLabel
已添加到next
以帮助解决此问题。 还有一个关于next
分支的演示,它具有排序的列。
@NeXTs其实我不知道你在哪里看到 redux 商店。 我在新对象中传递数据,因此它不会影响 redux 存储。
道具通常来自 redux 商店,这是我的观点
好吧,没关系,现在没那么重要了,还是谢谢你! :+1:
@NeXTs我使用对象传播将道具传递给表格,因此状态不会发生变化。
<SmartTable { ...{ tableHeaders, data, limit: 20, total: !!data && data.length, offset: 0, onPageClick: this.handleLoad } } />
@vorlov知道了
@nathanmarks哦,酷! 什么时候可以在 master 分支中使用?
上面缺少一个依赖项
从'./formatTableCell'导入formatTableCell;
@jimgong92 @chrisrittelmeyer formatTableCell 文件
import numeral from 'numeral';
import React from 'react';
import { Link } from 'react-router';
import FlatButton from 'material-ui/FlatButton';
export default (cell, format, row) => {
switch (format && format.type) {
case 'link':
return <Link to={ `${format.url}${row.id}` }>{ cell }</Link>;
case 'percentage':
return `${cell}%`;
case 'money':
return numeral(cell).format('0,0');
default:
return cell;
}
};
感谢更新。
@vorlov 你的组件很棒,你应该把它放在 gist 或 repo 示例中
@nathanmarks TableSortLabel
的链接和next
分支上的演示在哪里?
是的,在 repo 中没有 TableSortLabel 的痕迹或任何可排序性。 想知道为什么这个问题被关闭了。 不过,感谢@vorlov的出色工作。
是的,在 repo 中没有 TableSortLabel 的痕迹或任何可排序性。
它在next
分支上: demos/tables/EnhancedTable 。
@oliviertassinari我试过你的例子但是我得到这个错误:
TypeError: Cannot read property 'render' of undefined
EnhancedTable.render
http://localhost:8004/app.a3611250a45594961d8c.js:122073:47
http://localhost:8004/app.a3611250a45594961d8c.js:11761:22
measureLifeCyclePerf
http://localhost:8004/app.a3611250a45594961d8c.js:11040:13
ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext
http://localhost:8004/app.a3611250a45594961d8c.js:11760:26
ReactCompositeComponentWrapper._renderValidatedComponent
http://localhost:8004/app.a3611250a45594961d8c.js:11787:33
ReactCompositeComponentWrapper.performInitialMount
http://localhost:8004/app.a3611250a45594961d8c.js:11327:31
ReactCompositeComponentWrapper.mountComponent
http://localhost:8004/app.a3611250a45594961d8c.js:11223:22
Object.mountComponent
http://localhost:8004/app.a3611250a45594961d8c.js:3816:36
ReactDOMComponent.mountChildren
http://localhost:8004/app.a3611250a45594961d8c.js:10366:45
ReactDOMComponent._createInitialChildren
http://localhost:8004/app.a3611250a45594961d8c.js:7453:33
它位于下一个分支:demos/tables/EnhancedTable。
@oliviertassinari抱歉打扰。 似乎当我运行npm install material-ui@next
以安装此 EnhancedTable 所在的预发布包时,生成的 material-ui-build 文件夹中缺少 TableSortLabel 组件。 我在这里错过了关键步骤吗? 提前致谢。
@GarrettVD ~ next
分支还没有发布,所以你必须从 github 安装 npm。~
编辑:我们已经发布了一个早期的 alpha。
@mbrookes啊,明白了。 谢谢。
干得好,对这个功能很感兴趣。 谢谢
@oliviertassinari在下一个分支上也可以排序和分页吗? 该分支何时公开或合并到当前分支? 里面有很多有趣的东西:)
@damianobarbati我们发布了早期的 alpha: npm install material-ui@next
对于其他正在寻找 alpha 文档的人: https: //material-ui-1dab0.firebaseapp.com/#/component -demos/tables
嗨,新手登记入住。分类表会很可爱! 什么时候将其合并到 MUI 的稳定生产版本中?
等待此版本能够对我的表中的数据进行排序。 做得好!
你好,
我看到有一个新版本,但我似乎无法在源代码中找到排序功能。 我错过了什么吗?
@nshung你需要使用material-ui@next
https://material-ui-1dab0.firebaseapp.com/component-demos/tables
这很棒。 我在下一个演示中看到了动态排序。 您认为在此处添加对动态过滤的支持是否有意义? 这超出了这个组件的范围吗? 在 MUI 之外实施会更好吗?
@lrettig动态排序是在用户空间中实现的,我认为我们应该对动态过滤做同样的事情。 为什么? 因为用 20% 的努力覆盖 80% 的用例要容易得多。 我们从 master 分支了解到,人们对表格有各种各样的用例。
嗨@oliviertassinari感谢您的反馈。 不过,我有点困惑——这里没有将排序添加到下一个分支吗? 那么这不会让它成为未来的主人吗? 抱歉,如果我遗漏了一些明显的东西。
@lrettig对,下一个分支最终将合并到主分支中。
期待这个上线。
@oliviertassinari——谢谢! 但我仍然对你之前的评论感到困惑。 你建议:
动态排序是在用户空间实现的,我认为我们应该对动态过滤做同样的事情
但是,如果排序在这里,在下一个分支中,并且将转到 master,这是否意味着它_not_ 在用户空间中? 我错过了什么吗?
再次感谢。
@lrettig通过用户空间,我的意思是它可以在 Material-UI 之外实现。 这就是在 next/v1-alpha 分支演示中所做的。
我看到这是关闭的。 这在不是material-ui@next
的版本中可用吗? 如果可能的话,我想暂时锁定一个版本。
@jspengeman @next
是一个别名,正如我们所说,它的目标是v1.0.0-alpha.21
。
@oliviertassinari谢谢! 我明白了,刚刚看到它是在 2015 年开放的,我想知道该功能是否已经成为 0.X 版本。 假设答案是否定的?
这个功能是如何进入material-ui的发布的?
@oliviertassinari怎么样了?
该功能尚未进入 Material-UI。 但是,我们在v1 的文档中演示了如何实现它。
@oliviertassinari 谢谢你的快速回复!
最有用的评论
类似的东西