0

我试图弄清楚如何从 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/干锅/问题/ 586

我真的不明白这如何与 redux 和 connect 函数一起使用,但上面的示例工作得很好。

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

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

4

2 回答 2

0

假设您正在使用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预计将在外部进行管理。

于 2018-05-01T18:26:33.070 回答
0

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

首先,我覆盖了 TableBody griddle-component 并做了一个小修复以使其在 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>
    );
};
}
于 2017-06-05T12:46:56.930 回答