7

我正在尝试在成功执行自定义操作后刷新列表。

我在休息教程中使用了管理员的传奇

function * actionApproveSuccess () {
  yield put(showNotification('Executed'))
  yield put(push('/comments')) 
  // does not refresh, because the route does not change
  // react-redux-router also has no refresh() method, like react-router has...
}

我的另一个想法是以某种方式触发列表组件的刷新操作,但我不知道如何访问它或如何将它连接到 ACTION_SUCCESS 事件。

4

7 回答 7

6

没有办法通过反应路由器刷新路由,这是一个已知问题。Admin-on-rest 的List组件有自己的刷新机制,但没有提供任何 API。

我的建议是使用<List>基于 admin-on-rest 的自定义组件。如果您找到了公开refresh操作的方法,请随时在 aor 存储库上打开 PR!

于 2017-04-06T11:45:13.487 回答
4

@Danila Smirnov 上面的回答在我现在使用它时显示了这条消息:

弃用警告:刷新列表视图的首选方法是将自定义按钮与 redux 连接并调度 refreshView 操作。

现在单击刷新按钮本身也不起作用。

这是我在我的工作中的调整版本。

编辑:对其进行了更多修改以使其可重用。


RefreshListActions.js

import React, { Component } from 'react'
import FlatButton from 'material-ui/FlatButton'
import { CardActions } from 'material-ui/Card'
import NavigationRefresh from 'material-ui/svg-icons/navigation/refresh'
import { connect } from 'react-redux'
import { REFRESH_VIEW } from 'admin-on-rest/src/actions/uiActions'
import { refreshView as refreshViewAction } from 'admin-on-rest/src/actions/uiActions'

class MyRefresh extends Component {
    componentDidMount() {
        const { refreshInterval, refreshView } = this.props
        if (refreshInterval) {
            this.interval = setInterval(() => {
                refreshView()
            }, refreshInterval)
        }
    }

    componentWillUnmount() {
        clearInterval(this.interval)
    }

    render() {
        const { label, refreshView, icon } = this.props;
        return (
            <FlatButton
                primary
                label={label}
                onClick={refreshView}
                icon={icon}
            />
        );
    }
}

const RefreshButton = connect(null, { refreshView: refreshViewAction })(MyRefresh)

const RefreshListActions = ({ resource, filters, displayedFilters, filterValues, basePath, showFilter, refreshInterval }) => (
    <CardActions>
        {filters && React.cloneElement(filters, { resource, showFilter, displayedFilters, filterValues, context: 'button' }) }
        <RefreshButton primary label="Refresh" refreshInterval={refreshInterval} icon={<NavigationRefresh />} />
    </CardActions>
);

export default RefreshListActions

在我想要经常刷新的列表中:

import RefreshListActions from './RefreshListActions'

export default (props) => (
    <List {...props}
        actions={<RefreshListActions refreshInterval="10000" />}
        >
        <Datagrid>
            ...
        </Datagrid>
    </List>
)
于 2017-10-05T02:32:48.557 回答
3

绝对是hacky,但解决方法可能是:

push('/comments/1') //any path to change the current route
push('/comments') //the path to refresh, which is now a new route
于 2017-06-21T19:56:35.783 回答
2

通过 redux 使用 refreshView 操作效果很好。

看例子....

import { refreshView as refreshViewAction } from 'admin-on-rest';
import { connect } from 'react-redux'; 

class MyReactComponent extends Component {
  //... etc etc standard react stuff...

 doSomething() {
    // etc etc do smt then trigger refreshView like below  
    this.props.refreshView();
 }
 render() {
   return <div>etc etc your stuff</div>
 }
}

export default connect(undefined, { refreshView: refreshViewAction })(
  MyReactComponent
);
于 2017-11-15T19:38:09.403 回答
1

我已经通过操作面板通过小技巧解决了这个任务。我确定这不是正确的解决方案,但在某些情况下它可以提供帮助:

class RefreshButton extends FlatButton {
  componentDidMount() {
    if (this.props.refreshInterval) {
      this.interval = setInterval(() => {
        this.props.refresh(new Event('refresh'))
      }, this.props.refreshInterval)
    }
  }

  componentWillUnmount() {
    clearInterval(this.interval)
  }
}

const StreamActions = ({ resource, filters, displayedFilters, filterValues, basePath, showFilter, refresh }) => (
  <CardActions>
    {filters && React.cloneElement(filters, { resource, showFilter, displayedFilters, filterValues, context: 'button' }) }
    <RefreshButton primary label="Refresh streams" onClick={refresh} refreshInterval={15000} refresh={refresh} icon={<NavigationRefresh />} />
  </CardActions>
);

export default class StreamsListPage extends Component {
  render() {
    return (
      <List
        {...this.props}
        perPage={20}
        actions={<StreamActions />}
        filter={{ active: true }}
        title='Active Streams'>
        <StreamsList />
      </List>
    )
  }
}

于 2017-08-16T16:30:46.000 回答
1

push只是 AOR 的重定向,似乎对我也不起作用。guleryuz 发布的内容对我来说是正确的。这是我在他的示例上所做的:

// Import Statement
import { refreshView as refreshViewAction } from 'admin-on-rest';

class RemoveButton extends Component {
handleClick = () => {
    const { refreshView, record, showNotification } = this.props;
    fetch(`http://localhost:33333/api/v1/batch/stage/${record.id}`, { method: 'DELETE' })
        .then(() => {
            showNotification('Removed domain from current stage');
            refreshView();
        })
        .catch((e) => {
            console.error(e);
            showNotification('Error: could not find domain');
        });
}

 render() {
    return <FlatButton secondary label="Delete" icon={<DeleteIcon />}onClick={this.handleClick} />;
 }
}

这些位也很重要:

RemoveButton.propTypes = {
record: PropTypes.object,
showNotification: PropTypes.func,
refreshView: PropTypes.func,
};

export default connect(null, {
showNotification: showNotificationAction,
refreshView: refreshViewAction,
})(RemoveButton);

所以它的工作方式是使用 AORrefreshViewAction作为道具函数。这使用底层调用为我填充数据网格,即GET_LIST. 这可能不适用于您的特定用例。如果您有任何问题,请告诉我。

于 2017-12-12T19:23:38.373 回答
0

Pim Schaaf 的解决方案对我来说就像一个魅力,我的看起来有点不同

yield put(push('/comments/-1')); // This refreshes the data
yield put(showNotification('')); // Hide error 
于 2018-05-30T12:22:44.683 回答