如何在React Admin自定义批量操作按钮中取消选择列表项

时间:2019-01-07 14:10:55

标签: reactjs material-ui react-admin

我有一个react admin项目,并且已经实现了将列表视图的自定义按钮传递到bulkActionButtons属性中,如此处的文档所述:https://marmelab.com/react-admin/List.html#bulk-action-buttons

const BulkUserActions = props => (
  <MakeAdminButton {...props}/>
);

const UserList = props => (
  <List {...props} bulkActionButtons={<BulkUserActions/>}>
    <Datagrid rowClick="show">
      <TextField source="id"/>
      <EmailField source="email"/>
    </Datagrid>
  </List>
);

MakeAdminButton处理点击并执行我需要的更新。难题中缺少的部分是如何在操作完成后取消选择列表项。 props.selectedIds受保护,因此我在完成逻辑后无法简单地将其设置为空数组。

问题是如何在完成时取消设置props.selectedIds或其他取消选择列表项的方法。

const MakeAdminButton = withStyles(styles)(class MakeAdminButton extends React.Component {

  handleAction = () => {
    //does the stuff as required using this.props.selectedIds

    //what to return to unset this.props.selectedIds 
  };

  render () {
    return <Button variant="contained"
               color="primary"
               onClick={this.handleAction}
    <AdminIcon/>
  </Button>;
  }
});

3 个答案:

答案 0 :(得分:0)

每次单击复选框时都要设置一些元数据,以便将true或false注入到数组中,例如:

listData = {
   ...
   isChecked : true
}

然后在处理批量操作的函数内部,添加[listData].filter( )(lodash过滤器更快),检查并查看哪个isChecked === true,然后将它们设置为false,并更新{复选框输入标签上的{1}}属性。

答案 1 :(得分:0)

解决方案是从react admin调用批量助手功能:

class MakeAdminButton extends React.Component {

handleAction = () => {
 const { basePath, crudUpdateMany, resource, selectedIds } = this.props;

 //custom code goes in here...

 //calling this function triggers the unset and closes the toolbar
 crudUpdateMany(resource, selectedIds, { isAdmin: true }, basePath);
 };

render () {
  return <Button label="Make Admin" onClick={this.handleAction}>
    <AdminIcon/>
  </Button>;
 }
};

const BulkUserActions = connect(undefined, { crudUpdateMany })(MakeAdminButton);

const UserList = props => (
 <List {...props} bulkActionButtons={<BulkUserActions/>}>
  <Datagrid>
   <TextField source="id"/>
   <EmailField source="email"/>
   <BooleanField source="isAdmin" label="Admin" />
 </Datagrid>
</List>
);

如果我不正确地阅读它,则会在此页面上显示一个示例: https://github.com/marmelab/react-admin/blob/master/docs/List.md#bulk-action-buttons

答案 2 :(得分:0)

React Admin提供了实现方法。在v3上直接使用useUnselectAll或在useMutation的onSuccess回调中,使用useUpdateMany和useDataProvider挂钩。在带有dataProvider的v2版本上,withDataProvider装饰器的第四个参数,或者将自定义redux动作的meta.onSuccess.unselectAll设置为true,或者自动使用crudUpdateMany或Mutation组件的option属性。

对于带有crudUpdateMany的v2,goto Mike Miller回答。

工作示例:

https://codesandbox.io/s/exciting-firefly-dd1ni?file=/src/App.js

v3:

const UnselectAllButtonV3Hook = props => {
  const unselectAll = useUnselectAll();

  return (
    <Button
      onClick={() => {
        unselectAll(props.resource);
      }}
    >
      Unselect all with v3 hook
    </Button>
  );
};

https://marmelab.com/react-admin/doc/3.5/Actions.html#handling-side-effects-in-usedataprovider

useUpdateMany / useDataProvider / useMutation钩子,从unselectAll()调用on useUnselectAll()的onSuccess回调

const MakeAdminButtonV3 = props => {
  const refresh = useRefresh();
  const unselectAll = useUnselectAll();

  const [makeAdmin, { loading }] = useUpdateMany(
    props.resource,
    props.selectedIds,
    { isAdmin: true },
    {
      onSuccess: () => {
        unselectAll(props.resource);
        refresh();
      }
    }
  );

  //OR

  const dataProvider = useDataProvider();

  const makeAdmin2 = () => {
    dataProvider.updateMany(
      props.resource,
      { ids: props.selectedIds, data: { isAdmin: true } },
      {
        onSuccess: () => {
          unselectAll(props.resource);
          refresh();
        }
      }
    );
  };

  //OR

  const [makeAdmin3, { loading3 }] = useMutation(
    {
      type: "updateMany",
      resource: props.resource,
      payload: { ids: props.selectedIds, data: { isAdmin: true } }
    },
    {
      onSuccess: () => {
        unselectAll(props.resource);
        refresh();
      }
    }
  );

  return (
    <Button onClick={makeAdmin3} disabled={loading3}>
      Make Admin with V3 dataProvider hooks
    </Button>
  );
};

https://marmelab.com/react-admin/doc/3.5/Actions.html#usemutation-hook

https://marmelab.com/react-admin/doc/3.5/Actions.html#usedataprovider-hook

https://marmelab.com/react-admin/doc/3.5/Actions.html#specialized-hooks

V2示例也可以在v3上运行,但是Mutation和withDataProvider是旧版,直接使用dataProvider时会有很小的变化,因为v3上的dataProvider api已更改。

https://marmelab.com/react-admin/doc/3.5/Actions.html#legacy-components-query-mutation-and-withdataprovider

v2:

withDataProvider:

const UnmakeAdminButtonWithWithDataProvider = withDataProvider(
  class extends React.Component {
    handleClick = () => {
      this.props.dataProvider(
        UPDATE_MANY,
        "users",
        { ids: this.props.selectedIds, data: { isAdmin: false } },
        { onSuccess: { unselectAll: true, refresh: true } }
      );
    };

    render() {
      return (
        <Button onClick={this.handleClick}>
          Unmake Admin with withDataProvider
        </Button>
      );
    }
  }
);

https://marmelab.com/react-admin/doc/2.9/Actions.html#handling-side-effects

自定义redux动作:

import { connect } from 'react-redux';

const MAKE_ADMIN = "MAKE_ADMIN";

const makeAdmin = ids => ({
  type: MAKE_ADMIN,
  payload: { ids, data: { isAdmin: true } },
  meta: {
    fetch: UPDATE_MANY,
    resource: "users",
    onSuccess: { unselectAll: true, refresh: true }
  }
});

const MakeAdminButtonWithCustomAction = connect(
  null,
  { makeAdmin }
)(
  class extends React.Component {
    handleClick = () => {
      this.props.makeAdmin(this.props.selectedIds);
    };

    render() {
      return (
        <Button onClick={this.handleClick}>
          Make Admin With Custom Redux Action
        </Button>
      );
    }
  }
);

https://marmelab.com/react-admin/doc/2.9/Actions.html#adding-side-effects-to-actions

突变成分:

const MakeAdminMutationV2 = props => (
  <Mutation
    type="updateMany" //{UPDATE_MANY}
    resource={props.resource}
    payload={{ ids: props.selectedIds, data: { isAdmin: true } }}
    options={{
      onSuccess: {
        unselectAll: true,
        refresh: true
      }
    }}
  >
    {approve => <Button onClick={approve}>Make admin with Mutation</Button>}
  </Mutation>
);

https://marmelab.com/react-admin/doc/2.9/Actions.html#query-and-mutation-components