[2]React 深入浅出-----React的一个高级表格实现功能
程序员文章站
2022-04-19 19:36:31
...
在我们平常的企业级应用程序里面,表格形式的数据的展现和搜索是非常常见的。一般的做法都是在列表的上面,加几个搜索条件,然后最下面放一个搜索按钮,然后通过调用后台的Ajax进行过滤,然后调用JQuery等其他框架,进行 DOM书的更新,当然这个也是一个好的实现方法,但是就是有一点不太优雅。而且不是所见即所得,比如,必须输入了所有的输入条件,才能进行结构的搜索,而且把数据传输到后端,在传回来,性能上不是特别的好。 那么有没有更好的方法,刚好笔者这段时间在学习React,看到了Stoyan Stefanov写的一本书,里面提到了一种个人感觉比较优雅的方式,而且结合React框架本身的性能优势,我想用户体验应该是挺不错的。
Stoyan的设计的例子如下:
@静态效果:
@动态效果
其具体代码如下:
<!DOCTYPE html>
<html>
<head>
<title>Table</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="03.00.table.css">
</head>
<body>
<div id="app">
<!-- my app renders here -->
</div>
<script src="react/build/react.js"></script>
<script src="react/build/react-dom.js"></script>
<script>
var Excel = React.createClass({
displayName: 'Excel',
propTypes: {
headers: React.PropTypes.arrayOf(
React.PropTypes.string
),
initialData: React.PropTypes.arrayOf(
React.PropTypes.arrayOf(
React.PropTypes.string
)
),
},
getInitialState: function() {
return {
data: this.props.initialData,
sortby: null,
descending: false,
edit: null, // [row index, cell index],
search: false,
};
},
_sort: function(e) {
var column = e.target.cellIndex;
var data = this.state.data.slice();
var descending = this.state.sortby === column && !this.state.descending;
data.sort(function(a, b) {
return descending
? (a[column] < b[column] ? 1 : -1)
: (a[column] > b[column] ? 1 : -1);
});
this.setState({
data: data,
sortby: column,
descending: descending,
});
},
_showEditor: function(e) {
this.setState({edit: {
row: parseInt(e.target.dataset.row, 10),
cell: e.target.cellIndex,
}});
},
_save: function(e) {
e.preventDefault();
var input = e.target.firstChild;
var data = this.state.data.slice();
data[this.state.edit.row][this.state.edit.cell] = input.value;
this.setState({
edit: null,
data: data,
});
},
_preSearchData: null,
_toggleSearch: function() {
if (this.state.search) {
this.setState({
data: this._preSearchData,
search: false,
});
this._preSearchData = null;
} else {
this._preSearchData = this.state.data;
this.setState({
search: true,
});
}
},
_search: function(e) {
var needle = e.target.value.toLowerCase();
if (!needle) {
this.setState({data: this._preSearchData});
return;
}
var idx = e.target.dataset.idx;
var searchdata = this._preSearchData.filter(function(row) {
return row[idx].toString().toLowerCase().indexOf(needle) > -1;
});
this.setState({data: searchdata});
},
render: function() {
return (
React.DOM.div(null,
this._renderToolbar(),
this._renderTable()
)
);
},
_renderToolbar: function() {
return React.DOM.button(
{
onClick: this._toggleSearch,
className: 'toolbar',
},
'search'
);
},
_renderSearch: function() {
if (!this.state.search) {
return null;
}
return (
React.DOM.tr({onChange: this._search},
this.props.headers.map(function(_ignore, idx) {
return React.DOM.td({key: idx},
React.DOM.input({
type: 'text',
'data-idx': idx,
})
);
})
)
);
},
_renderTable: function() {
return (
React.DOM.table(null,
React.DOM.thead({onClick: this._sort},
React.DOM.tr(null,
this.props.headers.map(function(title, idx) {
if (this.state.sortby === idx) {
title += this.state.descending ? ' \u2191' : ' \u2193'
}
return React.DOM.th({key: idx}, title);
}, this)
)
),
React.DOM.tbody({onDoubleClick: this._showEditor},
this._renderSearch(),
this.state.data.map(function(row, rowidx) {
return (
React.DOM.tr({key: rowidx},
row.map(function(cell, idx) {
var content = cell;
var edit = this.state.edit;
if (edit && edit.row === rowidx && edit.cell === idx) {
content = React.DOM.form({onSubmit: this._save},
React.DOM.input({
type: 'text',
defaultValue: cell,
})
);
}
return React.DOM.td({
key: idx,
'data-row': rowidx,
}, content);
}, this)
)
);
}, this)
)
)
);
}
});
var headers = [
"Book", "Author", "Language", "Published", "Sales"
];
var data = [
["The Lord of the Rings", "J. R. R. Tolkien", "English", "1954-1955", "150 million"],
["Le Petit Prince (The Little Prince)", "Antoine de Saint-Exupéry", "French", "1943", "140 million"],
["Harry Potter and the Philosopher's Stone", "J. K. Rowling", "English", "1997", "107 million"],
["And Then There Were None", "Agatha Christie", "English", "1939", "100 million"],
["Dream of the Red Chamber", "Cao Xueqin", "Chinese", "1754-1791", "100 million"],
["The Hobbit", "J. R. R. Tolkien", "English", "1937", "100 million"],
["She: A History of Adventure", "H. Rider Haggard", "English", "1887", "100 million"],
];
var Ex = ReactDOM.render(
React.createElement(Excel, {
headers: headers,
initialData: data,
}),
document.getElementById("app")
);
</script>
</body>
</html>
代码参考:https://github.com/stoyan/react
上一篇: Bootstrap Table学习
下一篇: 一个漂亮的暗系色调网站主页,外表美观。