简体   繁体   English

如何在反应管理员自定义批量操作按钮中取消选择列表项

[英]How to deselect list items in react admin custom bulk action buttons

I have a react admin project and have implemented a custom button for the List view passed into the bulkActionButtons attribute as described by the docs here: https://marmelab.com/react-admin/List.html#bulk-action-buttons我有一个反应管理项目,并为传递到bulkActionButtons属性的列表视图实现了一个自定义按钮, bulkActionButtons的文档所述: https : bulkActionButtons

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

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

The MakeAdminButton handles the click and performs the update that I need. MakeAdminButton处理点击并执行我需要的更新。 The missing piece of the puzzle is how to deselect the list items after the action is completed.拼图的缺失部分是如何在操作完成后取消选择列表项。 The props.selectedIds is protected so I am unable to simply set this to an empty array after completing my logic. props.selectedIds受到保护,因此我无法在完成逻辑后简单地将其设置为空数组。

Question is how to unset props.selectedIds or other method for deselecting the list items on completion.问题是如何取消设置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>;
  }
});

React Admin provide ways of doing it. React Admin 提供了这样做的方法。 On v3 directly with useUnselectAll or on onSuccess callback of useMutation, useUpdateMany and useDataProvider hooks.在 v3 上直接使用 useUnselectAll 或 onSuccess 回调的 useMutation、useUpdateMany 和 useDataProvider 钩子。 On v2 with dataProvider fourth argument of withDataProvider decorator or seting meta.onSuccess.unselectAll to true of custom redux actions, or automatically with crudUpdateMany, or options prop of Mutation component.在 v2 上使用 withDataProvider 装饰器的 dataProvider 第四个参数或将 meta.onSuccess.unselectAll 设置为自定义 redux 操作的 true,或自动使用 crudUpdateMany 或 Mutation 组件的 options 属性。

For v2 with crudUpdateMany, goto Mike Miller answer.对于带有 crudUpdateMany 的 v2,请goto Mike Miller 的答案。

Working examples:工作实例:

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

v3: 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 https://marmelab.com/react-admin/doc/3.5/Actions.html#handling-side-effects-in-usedataprovider

useUpdateMany/useDataProvider/useMutation hooks, onSuccess callback calling unselectAll() from useUnselectAll() useUpdateMany/useDataProvider/useMutation 钩子,onSuccess 回调从useUnselectAll()调用unselectAll() useUnselectAll()

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#usemutation-hook

https://marmelab.com/react-admin/doc/3.5/Actions.html#usedataprovider-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 https://marmelab.com/react-admin/doc/3.5/Actions.html#specialized-hooks

V2 examples also work on v3, but Mutation and withDataProvider is legacy, with a small change while using dataProvider directly, since dataProvider api on v3 changed. V2 示例也适用于 v3,但 Mutation 和 withDataProvider 是遗留的,在直接使用 dataProvider 时有一个小的变化,因为 v3 上的 dataProvider api 发生了变化。

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

v2: v2:

withDataProvider: 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 https://marmelab.com/react-admin/doc/2.9/Actions.html#handling-side-effects

custom redux action:自定义还原操作:

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 https://marmelab.com/react-admin/doc/2.9/Actions.html#adding-side-effects-to-actions

Mutation component:突变成分:

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 https://marmelab.com/react-admin/doc/2.9/Actions.html#query-and-mutation-components

Set up some meta data for each time you click the checkbox, so it injects true or false into the array like:每次单击复选框时都设置一些元数据,以便将 true 或 false 注入数组,例如:

listData = {
   ...
   isChecked : true
}

Then inside the function that handles the bulk operations, add a [listData].filter( ) , (lodash filter is faster), to check and see which isChecked === true , and then set them to false, and update the value={bool} attribute on the checkbox input tag.然后在处理批量操作的函数内部,添加一个[listData].filter( ) ,(lodash 过滤器更快),检查并查看哪个isChecked === true ,然后将它们设置为 false,并更新value={bool}复选框输入标签上的value={bool}属性。

The solution is to call a bulk helper function from react admin:解决方案是从 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>
);

An example is shown on this page if I had bothered to read it properly: https://github.com/marmelab/react-admin/blob/master/docs/List.md#bulk-action-buttons如果我懒得正确阅读,此页面上会显示一个示例: https : //github.com/marmelab/react-admin/blob/master/docs/List.md#bulk-action-buttons

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM