一个屏幕上带有过滤器的多个 React 管理列表

问题描述 投票:0回答:3

我们已经基于 React Admin 构建了一个管理 UI,并且在某些情况下我们希望在单个屏幕上使用多个列表以方便使用。例如。在用户详细信息视图中,我们希望显示用户存档的多个地址以及用户进行的购买。用户、地址和购买都是 RA 术语中的“资源”。

大致是这样的:

/* file <...>/resources/users/UserShow.js */

import AddressList from '../addresses/AddressList';
import PurchaseList from '../purchases/PurchaseList';

const UserShow = ({ id, classes, translate, ...props }) => (
    <Fragment>
        <Show id={id} {...props}>
            ...render user details here...
        </Show>
        <AddressList {...props} basePath={'/addresses'} resource={'addresses'} filter={{ userId: id }} />
        <PurchaseList {...props} basePath={'/purchases'} resource={'purchases'} filter={{ userId: id }} />
    </Fragment>
);

大部分看起来都很好用,但过滤器让我们有些头疼。它周围的一切似乎都是一次为一个过滤器构建的,没有任何自定义方式(例如指定一个属性用于 redux 和 React-router 存储中的过滤器,而不是使用硬编码的属性)

有没有人曾经在同一屏幕上制作过两个可过滤列表,并且有更多的指针?

reactjs react-admin
3个回答
1
投票

我最终想出了一个我想分享的解决方法。

问题在于 RA 将过滤器/页面/排序值传播到查询中,并维护过滤器对象的“签名”(相应 JSON 的字符串表示形式),以在 URL 发生变化时检测当前过滤器的变化。通过这种方法,当用户来回导航时,过滤器和分页值保持活动状态,并且仅在实际字段值发生变化时才会更新。

如果每个屏幕有一个列表,这是一件好事,但在我们的例子中,一个列表的过滤器更新会导致值反向传播到屏幕上的每个其他列表中。

首先,我尝试通过修改查询来保留所有过滤器,以便每个过滤器都使用其资源名称作为键。不幸的是,这导致了大量的更改,包括由于修补 RA 内部而复制整个 RA 组件。

注意:RA 已经在其 Redux 存储中保留了每个资源的过滤器值,因此我无法理解为什么他们不使用类似的语法/方法进行查询。

另一种选择是完全切断查询的传播。权衡是您无法为特定搜索添加书签,并且在导航时需要重新激活过滤器,但这似乎是一个很小且可以接受的缺点。

这是 RA 3 中更新查询的相关代码:https://github.com/marmelab/react-admin/blob/master/packages/ra-core/src/controller/useListParams.ts#L164

history.push({
    search: `?${stringify({
        ...newParams,
        filter: JSON.stringify(newParams.filter),
        displayedFilters: JSON.stringify(newParams.displayedFilters),
    })}`,
});

无法直接修改此行为,但我们可以向 RA 提供我们自己的历史记录实现并覆盖搜索参数。相应的猴子补丁看起来像这样:

const history = createBrowserHistory({
    basename: process.env.PUBLIC_URL
});

const oldPush = history.push;
history.push = state => {
    oldPush({
        ...state,
        search: null,
    });
};

然后可以像这样使用:

const App = () => (
    <Admin
        history={history}
        ...
    >
        ...
    </Admin>
);

0
投票

在反应管理中你也有组件

<ReferenceManyField> 

<ReferenceManyToManyField>

它允许您从与用户相关的其他表中获取记录。


0
投票

您可以使用属性

disableSyncWithLocation
禁用列表参数与当前位置(URL搜索参数)的同步。

文档:https://marmelab.com/react-admin/List.html#disablesyncwithlocation

© www.soinside.com 2019 - 2024. All rights reserved.