微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

[2]React 深入浅出-----React的一个高级表格实现功能

在我们平常的企业级应用程序里面,表格形式的数据的展现和搜索是非常常见的。一般的做法都是在列表的上面,加几个搜索条件,然后最下面放一个搜索按钮,然后通过调用后台的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,});
            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","1997","107 million"],["And Then There Were None","Agatha Christie","1939","100 million"],["Dream of the Red ChAmber","Cao Xueqin","Chinese","1754-1791",["The Hobbit","1937",["She: A History of Adventure","H. Rider Haggard","1887",];
      
      var Ex = ReactDOM.render(
        React.createElement(Excel,{
          headers: headers,initialData: data,}),document.getElementById("app")
      );
    </script>
  </body>
</html>


代码参考:https://github.com/stoyan/react

原文地址:https://www.jb51.cc/react/303259.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐