【问题标题】:How to refresh a List View in admin on rest如何在休息时在管理员中刷新列表视图
【发布时间】:2017-04-04 16:19:40
【问题描述】:

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

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

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 事件。

【问题讨论】:

    标签: reactjs react-redux admin-on-rest


    【解决方案1】:

    没有办法通过反应路由器刷新路由,那是known problem。 Admin-on-rest 的 List 组件有 its own refresh mechanism,但没有提供任何 API。

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

    【讨论】:

      【解决方案2】:

      @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>
      )
      

      【讨论】:

      • 这是有效的。最好创建具有​​自动更新间隔下拉菜单的按钮,例如禁用、10、50、100 等。我在另一篇文章stackoverflow.com/questions/44551957/… 中看到有人有类似的想法。但没有运气让它工作
      【解决方案3】:

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

      push('/comments/1') //any path to change the current route
      push('/comments') //the path to refresh, which is now a new route
      

      【讨论】:

        【解决方案4】:

        通过 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
        );
        

        【讨论】:

        • 这对我在执行自定义操作后刷新列表很有用。非常感谢!
        • 太棒了,但是如果你不想调度并只听刷新,那么我可以修复 UI 而不是使用 react-admin 组件构建的问题怎么办?
        【解决方案5】:

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

        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>
            )
          }
        }

        【讨论】:

        • 刚试了一下,它显示一个错误,并且这个通知:“弃用警告:刷新列表视图的首选方法是将您的自定义按钮与 redux 连接并调度 refreshView 操作。”
        • 这是一个旧版本的包。现代应用中不需要这个技巧
        【解决方案6】:

        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);
        

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

        【讨论】:

          【解决方案7】:

          Pim Schaaf's 解决方案对我来说很有魅力,我的看起来有点不同

          yield put(push('/comments/-1')); // This refreshes the data
          yield put(showNotification('')); // Hide error 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-07-15
            • 2011-10-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-11
            • 1970-01-01
            相关资源
            最近更新 更多