2

我正在将材料表用于 React 与远程数据,并添加了一个自定义 TextField 以便能够控制何时启动搜索查询,例如在按下 Enter 之后。发送新的搜索词时,我query.search用新的搜索词替换。我还意识到在新搜索后没有重新设置页码,现在将其重新设置为:

if (query.search !== searchTextValue) {
    query.page = 0
}

当使用新的搜索词时,是否有另一种方法来重新设置 Query 对象?

完整代码如下

class PublicationsMatTable extends React.Component {
    constructor(props) {
        super(props)

        this.state = ({
            value: '',
            searchValue: '',
        });
        this.handleChange = this.handleChange.bind(this);
        this.getUserFriendlyStatusLabels = this.getUserFriendlyStatusLabels.bind(this);
    }

    tableRef = React.createRef();

    // Get text input value
    handleChange(event) {
        this.setState({ value: event.target.value });
    }

    clearSearchInput = () => {
        // clear value
        this.setState({
            value: '',
            searchValue: '',
        })

        // refresh table
        if (this.tableRef.current) {
            this.tableRef.current.onQueryChange();
        }
    }


    /**
     * Set user friendly status label
     */
    getUserFriendlyStatusLabels(rowData) {
        if (rowData === 'UNDER_SUBMISSION' || rowData === 'UNDER_SUMMARY_STATS_SUBMISSION'
            || rowData === 'PUBLISHED_WITH_SS') {
            return 'CLOSED'
        }
        if (rowData === 'ELIGIBLE') {
            return 'OPEN FOR SUBMISSION'
        }
        if (rowData === 'PUBLISHED') {
            return 'OPEN FOR SUMMARY STATISTICS SUBMISSION'
        }
    }


    render() {
        const { classes } = this.props;
        const noResultsMessage = <span className={classes.noResultsTextStyle}>My custom message</span>;

        let { searchValue } = this.state;
        let searchTextValue = searchValue.trim();

        return (
            <Container className={classes.publicationContainer}>

                <Grid container
                    direction="row"
                    justify="center"
                    alignItems="center">
                    <Grid item>
                        <CssTextField
                            id="outlined-bare"
                            name="searchInput"
                            value={this.state.value}
                            className={classes.textField}
                            variant="outlined"
                            placeholder="Search by PubMedID or Author"
                            helperText="Enter an Author name, e.g. Yao, or PMID, e.g. 25533513"

                            onChange={this.handleChange}

                            onKeyPress={(event) => {
                                if (event.key === 'Enter') {
                                    event.preventDefault();
                                    this.setState({ value: event.target.value, searchValue: event.target.value });
                                    this.tableRef.current && this.tableRef.current.onQueryChange();
                                }
                            }}
                        />
                        <button label="Clear" onClick={this.clearSearchInput}> Clear </button>
                    </Grid>
                </Grid>

                {searchTextValue && (
                    <MaterialTable
                        tableRef={this.tableRef}
                        icons={tableIcons}
                        columns={[
                            {
                                title: 'PubMedID', field: 'pmid',
                                render: rowData => (<Link to={{
                                    pathname: `${process.env.PUBLIC_URL}/publication/${rowData.pmid}`,
                                    state: { pmid: rowData.pmid }
                                }}
                                    style={{ textDecoration: 'none' }}>{rowData.pmid}</Link>)
                            },
                            { title: 'First author', field: 'firstAuthor', },
                            { title: 'Publication', field: 'title' },
                            { title: 'Journal', field: 'journal' },
                            {
                                title: 'Status', field: 'status',
                                render: rowData => (this.getUserFriendlyStatusLabels(rowData.status))
                            },
                        ]}
                        data={query =>
                            new Promise((resolve, reject) => {

                                // Re-set search page for new query
                                if (query.search !== searchTextValue) {
                                    query.page = 0
                                }

                                // Replace search text value in Query object with input from TextField
                                query.search = searchTextValue;

                                let url = GET_PUBLICATIONS_URL

                                // Handle search by PubMedID
                                let onlyNumbers = /^\d+$/;

                                if (query.search) {
                                    if (onlyNumbers.test(query.search)) {
                                        url += '/' + query.search + '?pmid=true'
                                        fetch(url)
                                            .then(response => response.json())
                                            .then(result => {
                                                resolve({
                                                    data: [result],
                                                    page: 0,
                                                    totalCount: 1,
                                                })
                                            }).catch(error => {
                                            })
                                    }
                                    // Handle search by Author
                                    else {
                                        url += '?author=' + query.search
                                        url += '&size=' + query.pageSize
                                        url += '&page=' + (query.page)
                                        console.log("** URL: ", url);

                                        // Handle sorting search by Author results
                                        // if (query.orderBy) {
                                        //     let sortOrder = query.orderDirection;
                                        //     url += '&sort=' + query.orderBy.field + ',' + sortOrder
                                        // }
                                        // else {
                                        // Sort search by Author results asc by default
                                        // Note: Sorting is supported for only 1 column
                                        // url += '&sort=firstAuthor,asc'
                                        // TODO: Check if sorting is still supported
                                        // url = url
                                        // }

                                        fetch(url)
                                            .then(response => response.json())
                                            .then(result => {
                                                resolve({
                                                    data: result._embedded.publications,
                                                    page: result.page.number,
                                                    totalCount: result.page.totalElements,
                                                })
                                            }).catch(error => {
                                            })
                                    }
                                }
                                // Display all results
                                else {
                                    url += '?size=' + query.pageSize
                                    url += '&page=' + (query.page)

                                    // Handle sorting all results
                                    if (query.orderBy) {
                                        let sortOrder = query.orderDirection;
                                        url += '&sort=' + query.orderBy.field + ',' + sortOrder
                                    }

                                    fetch(url)
                                        .then(response => response.json())
                                        .then(result => {
                                            resolve({
                                                data: result._embedded.publications,
                                                page: result.page.number,
                                                totalCount: result.page.totalElements,
                                            })
                                        }).catch(error => {
                                        })
                                }
                                setTimeout(() => {
                                    resolve({
                                        data: [],
                                        page: 0,
                                        totalCount: 0,
                                    });
                                }, 3000);
                            })
                        }
                        options={{
                            pageSize: 10,
                            pageSizeOptions: [10, 20, 50],
                            debounceInterval: 250,
                            toolbar: false,
                        }}
                        localization={{
                            body: {
                                emptyDataSourceMessage: noResultsMessage
                            }
                        }}
                    />
                )}
            </Container>
        )
    }
}
4

1 回答 1

3

目前material-table不公开任何辅助方法,但您可以通过tableRef属性获取表组件的引用并直接操作它的内部和状态(以及其他内容)。并不是说我认为这是最佳实践。

于 2019-10-08T06:08:52.200 回答