【问题标题】:ReactJS - Griddle v1.0 get current filtered dataReactJS - Griddle v1.0 获取当前过滤数据
【发布时间】:2017-05-31 09:37:44
【问题描述】:

我试图弄清楚如何从 Griddle 组件中获取当前过滤的项目。

我在源代码中找到了以下函数:

var filteredDataSelector = exports.filteredDataSelector = (0, _reselect.createSelector)(dataSelector, filterSelector, function (data, filter){
        return data.filter(function (row) {
        return Object.keys(row.toJSON()).some(function (key) {
        return row.get(key) && 
        row.get(key).toString().toLowerCase().indexOf(filter.toLowerCase()) > -1;
      });
   });
});

但是我将如何在我的反应组件中使用过滤数据选择器?单击按钮导出到excel时,我想获取过滤后的项目。

我发现这个例子是关于如何与列表中的每个项目进行交互(呈现超链接而不仅仅是纯文本),我认为它应该以类似于我想要实现的方式工作: https://github.com/GriddleGriddle/Griddle/issues/586

我不太明白这如何与 redux 和 connect 函数一起使用,但上面的示例运行良好。

不确定我是否必须以类似的方式使用 redux/connect 来获取过滤后的项目列表?

Griddle 文档: https://griddlegriddle.github.io/Griddle/docs/

【问题讨论】:

    标签: javascript reactjs redux griddle


    【解决方案1】:

    找到了解决这个问题的方法,即使我很确定有更好的解决方案,请告诉我。

    首先,我重写了 TableBody 网格组件,还做了一个小修复,让它在 Internet Explorer 11 即 ie11 (list._tail.array) 中正常工作。我将当前过滤的数据行索引存储在 this.rowIds 中。

                    TableBody: (_ref) => {
                        var rowIds = _ref.rowIds,
                            Row = _ref.Row,
                            style = _ref.style,
                            className = _ref.className;
    
                        this.rowIds = rowIds._tail.array;
    
                        var list = rowIds && rowIds.map(function (r) {
                            return React.createElement(Row, { key: r, griddleKey: r });
                        });
    
                        //ie11 felsökningsfix:
                        //console.log(list);
                        //console.log(list._tail.array);
    
                        return React.createElement(
                            'tbody',
                            { style: style, className: className }, list._tail.array //fix för ie11! orginalkoden skickade bara in list, men krachade då i ie11.
                        );
                    }
    

    使用本文中解释的 rowDataSelector:https://griddlegriddle.github.io/Griddle/examples/getDataFromRowIntoCell/,然后使用 rowIds 字段获取所选数据,仅在第一个行索引处。

        this.rowDataSelector = (state, { griddleKey }) => {
            if (griddleKey === this.rowIds[0]) {
                this.selectedData = this.rowIds.map(function (id) {
                    return state.get('data')
                        .find(rowMap => rowMap.get('griddleKey') === id)
                        .toJSON();
                });
            } 
            return state
                .get('data')
                .find(rowMap => rowMap.get('griddleKey') === griddleKey)
                .toJSON();
        }
    

    使用它:

    exportToExcel() {
    if (this.selectedData.length != 0) {
        var results = this.selectedData;
        Api.exportToExcelPre('/product/exporttoexcelpre/', results).then(result => {
            window.location = Constants.API_URL + '/product/exporttoexcel/';
        });
    }
    }
    

    最终代码:

    import { connect } from 'react-redux';
    
    export default class ProductList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [],
            loading: true
        };
    }
    
    updateProductList() {
        Api.getProducts().then(products => {
            this.setState({ data: products, loading: false });
        });
    }
    
    componentDidMount() {
        this.updateProductList();
    }
    
    componentWillReceiveProps(props) {
        if (props.refreshProductList) {
            this.updateProductList();
        }
    }
    
    render() {
        if (this.state.loading) {
            return (
                <div>Läser in produkter...</div>
            );
        }
        return (
            <div>
                <ProductResultList products={this.state.data} />
            </div>
        );
    }
    }    
    class Filter extends Component {
    constructor(props) {
        super(props);
    }
    
    onChange(e) {
        this.props.setFilter(e.target.value);
    }
    
    render() {
        var imgExcelLogo = <img src={PathHelper.getCurrentPathAppend("img/excel_logo.png")} className="export-symbol" onClick={this.props.export} style={{ float: "right" }} />;
        return (
            <div>
                <div className="row">
                    <div className="form-group col-md-6 label-floating is-empty">
                        <label class="control-label" htmlFor="search-product">Sök på valfritt fält, exempelvis produktnamn/produktkategori osv.</label>
                        <input className="form-control" type="text" name="search-product" id="search-product" onChange={this.onChange.bind(this)} />
                    </div>
                    <div className="col-md-6 form-group" style={{ minHeight: "35px" }}>
                        {imgExcelLogo}
                    </div>
                </div>
            </div>
        );
    }
    }    
    
    export class ProductResultList extends Component {
    constructor(props) {
        super(props);
        this.rowIds = [];
        this.selectedData = [];
        this.styleConfig = {
            classNames: {
                Row: 'row-class',
                Cell: "col-md-2",
                TableHeadingCell: "col-md-2 cursor",
                Table: "table table-striped table-hover",
                Filter: "form-control"
            },
        }
        this.sortMethod = {
            data: this.props.products,
            column: "generatedId"
        }
        this.settings = {
            // The height of the table
            tableHeight: 100,
            // The width of the table
            tableWidth: null,
            // The minimum row height
            rowHeight: 10,
            // The minimum column width
            defaultColumnWidth: null,
            // Whether or not the header should be fixed
            fixedHeader: false,
            // Disable pointer events while scrolling to improve performance
            disablePointerEvents: false
        };
        this.pageProps = {
            currentPage: 1,
            pageSize: 1000
        }
    
        this.rowDataSelector = (state, { griddleKey }) => {
            if (griddleKey === 0) {
                this.selectedData = this.rowIds.map(function (id) {
                    return state.get('data')
                        .find(rowMap => rowMap.get('griddleKey') === id)
                        .toJSON();
                });
            } 
            return state
                .get('data')
                .find(rowMap => rowMap.get('griddleKey') === griddleKey)
                .toJSON();
        }
        this.exportToExcel = this.exportToExcel.bind(this);
        this.enhancedWithRowData = connect((state, props) => {
            return {
                // rowData will be available into MyCustomComponent
                rowData: this.rowDataSelector(state, props)
            };
        });
    }
    
    exportToExcel() {
        if (this.selectedData.length != 0) {
            var results = this.selectedData;
            Api.exportToExcelPre('/product/exporttoexcelpre/', results).then(result => {
                window.location = Constants.API_URL + '/product/exporttoexcel/';
            });
        }
    }
    
    LinkComponent({ value, griddleKey, rowData }) {
        return (
            <Link to={PathHelper.getCurrentPath() + "product/edit/" + rowData.id}>{rowData.name}</Link>
        );
    }
    
    render() {
        return (
            <Griddle
                ref='Griddle'
                styleConfig={this.styleConfig}
                data={this.props.products}
                pageProperties={this.pageProps}
                sortProperties={this.sortProperties}
                components={{
                    Layout: ({ Table, Filter }) => <div><Filter /><div className="table-responsive"><Table /></div></div>,
                    Settings: () => <span />,
                    SettingsContainer: () => <span />,
                    SettingsToggle: () => <span />,
                    PageDropdown: () => <span />,
                    NextButton: () => <span />,
                    Filter: (filter) => {
                        return <Filter products={this.props.products} export={this.exportToExcel} setFilter={filter.setFilter} />
                    },
                    TableBody: (_ref) => {
                        var rowIds = _ref.rowIds,
                            Row = _ref.Row,
                            style = _ref.style,
                            className = _ref.className;
    
                        this.rowIds = rowIds._tail.array;
    
                        var list = rowIds && rowIds.map(function (r) {
                            return React.createElement(Row, { key: r, griddleKey: r });
                        });
    
                        //ie11 felsökningsfix:
                        //console.log(list);
                        //console.log(list._tail.array);
    
                        return React.createElement(
                            'tbody',
                            { style: style, className: className }, list._tail.array //fix för ie11! orginalkoden skickade bara in list, men krachade då i ie11.
                        );
                    }
                }}
                plugins={[plugins.LocalPlugin]}>
                <RowDefinition>
                    <ColumnDefinition id="generatedId" title="Produkt-Id" />
                    <ColumnDefinition id="name" title="Namn" customComponent={this.enhancedWithRowData(this.LinkComponent)} />
                    <ColumnDefinition id="productCategoryName" title="Produktkategori" />
                    <ColumnDefinition id="productTypeName" title="Produkttyp" />
                    <ColumnDefinition id="supplierName" title="Leverantör" />
                    <ColumnDefinition id="toBeInspectedString" title="Besiktigas" />
                </RowDefinition>
            </Griddle>
        );
    };
    }
    

    【讨论】:

      【解决方案2】:

      假设您使用LocalPlugin,您将在增强器/容器中使用filteredDataSelector 将道具注入您的演示组件。大致:

      import React, { Component } from 'react';
      import Griddle, { connect } from 'griddle-react';
      import PropTypes from 'prop-types';
      import getContext from 'recompose/getContext';
      
      const FilterContainerEnhancer = OriginalComponent => compose(
        getContext({
          selectors: PropTypes.object
        }),
        connect((state, props) => ({
          filteredData: props.selectors.filteredDataSelector(state)
        }))
      )(props => <OriginalComponent {...props} />);
      
      class FilterWithFilteredData extends Component {
        setFilter = (e) => this.props.setFilter(e.target.value);
      
        render() {
          return (
            <div>
              <input
                type="text"
                name="filter"
                placeholder={this.props.placeholder}
                onChange={this.setFilter}
                style={this.props.style}
                className={this.props.className}
                />
              ({this.props.filteredData.length} rows)
            </div>
          );
        }
      }
      
      // ...
      
      return (
        <Griddle
          data={...}
          plugins={[LocalPlugin]}
          components={{
            FilterContainerEnhancer,
            Filter: FilterWithFilteredData
          }}
          />
      );
      

      如果您不使用 LocalPlugin,则您只能自己使用,因为 data 预计将由外部管理。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-26
        • 2013-06-20
        相关资源
        最近更新 更多