如何在由列表中的唯一值填充的 react-admin 列表中添加过滤器?

How to add a filter in react-admin List populated by unique values within the list?

可能是新手问题,但不能完全联系起来。我在列表中有一个过滤器组件:

const BrandFilter = (props) => (
    <Filter {...props}>
      <SearchInput source="q" alwaysOn />
      <RadioButtonGroupInput source="active" alwaysOn label="" choices={[
        { id: 'true', name: 'Active' },
        { id: 'false', name: 'Inactive' },
        { id: ' ', name: 'All' },
      ]} />
      <QuickFilter source="pursue" label="Pursue" resettable />
      <SelectInput label="Status" source="status" optionText="status" />
    </Filter>
  );

SelectInput 没有在下拉列表中显示任何内容。不确定是否可能,但我想显示一个下拉列表,其中包含记录中出现的唯一状态值。 Status 没有 FK 关系;它只是一个可以输入任何内容的文本字段。但是,我仍然希望用户能够看到下拉列表中的值和 select 一个。可能的?谢谢。

更新

我试图通过修改 api 以接受新的端点:/brands/statuses 并返回一个唯一的状态列表来添加一个唯一的状态列表作为参考记录。它确实在填充状态下拉列表中起作用。

App.js:

<Resource
  name="brands/statuses" />

Brand.js(过滤器组件)

  <ReferenceInput source="status" reference="brands/statuses" perPage={25}>
    <SelectInput label="Status" source="status" optionText="status" />
  </ReferenceInput>

但是,我收到一个错误,至少有一条记录没有 ID。我记得 react 期望记录有一个 id。所以,作为一个 hack,我将第一个品牌记录的 id 添加到 sql:

SELECT fpb.id, fpb.status FROM lookabout.fgm_product_brand fpb WHERE fpb.status IS NOT NULL GROUP BY fpb.status ORDER BY fpb.status

这导致在过滤器下拉列表中获得状态列表。但是,当我点击其中一个时,它发送了状态的id(实际上只是品牌记录的id)并且没有返回任何结果:

http://localhost:3010/brands/find?limit=15&page=1&orderBy=id&orderDir=ASC&filter={%22active%22:%22%20%22,%22status%22:2}

接近,但不完全是。我觉得我在强迫某些事情,因为我不太明白。或者,与 react-admin 的运作方式背道而驰?欢迎大家提出意见。谢谢。

最终更新

成功了。我没有使用品牌记录的 ID 作为替代状态 ID,而是使用了状态本身。因此,api 中的 sql 现在显示为:

SELECT fpb.status AS id, fpb.status FROM lookabout.fgm_product_brand fpb WHERE fpb.status IS NOT NULL GROUP BY fpb.status ORDER BY fpb.status

这为结果集提供了一个唯一的 ID,然后在通过过滤条件时使用该 ID。 HTTP GET 请求现在看起来像:

http://localhost:3010/brands/find?limit=15&page=1&orderBy=id&orderDir=ASC&filter={%22active%22:%22%20%22,%22status%22:%22Potential%22}

和returns预期的结果。感谢大家的帮助。

您是否尝试过用 <ReferenceInput /> 组件包装它?否则,您似乎必须定义 select 选项。

根据文档,用 ReferenceInput 包装它应该会根据源自动提取选项:


https://marmelab.com/react-admin/Inputs.html#selectinput

滚动到引用 SelectInput 的文本末尾,您将看到:


提示:如果您想用相关记录列表填充 choices 属性,您应该修饰 <SelectInput> with <ReferenceInput>,并将 choices 留空:

import { SelectInput, ReferenceInput } from 'react-admin';

    <ReferenceInput label="Author" source="author_id" reference="authors">
        <SelectInput optionText="last_name" />
    </ReferenceInput>

如果这不起作用,也许您可​​以获取数据并从那里定义您的选项。供参考:

<SelectInput source="category" allowEmpty emptyValue={null} choices={[
    { id: 'programming', name: 'Programming' },
    { id: 'lifestyle', name: 'Lifestyle' },
    { id: 'photography', name: 'Photography' },
]} />

我看到两个解决方案:

首先,创建新的 api 端点,例如 yourResourceStatuses 或 yourResource/statuses,这可能是最好但需要更多工作的方法,其中 returns 状态字段的独特唯一值,然后使用 ReferenceInput 引用此新资源作为您的 SelectInput 父级:

<Filter>
    ....
    <ReferenceInput source="status" reference="resourceStatuses">
        <SelectInput label="Status" source="status" optionText="status" />
    </ReferenceInput>
<Filter/>

您还需要在 Admin 下声明此类资源,仅使用 name prop,允许 react-admin 初始化它的 redux 存储。

<Admin>
    ....
    <Resource name="resourceStatuses"/>
</Admin>

如果您使用 SQL,这可以像

一样简单
SELECT DISTINCT status from 'table';

第二个,可能会使下拉列表中出现重复的状态值,但如果您的 api 支持在状态字段上进行文本搜索,则需要较少的工作。正在为 AutocompleteInput 更改 SelectInput 并用具有相同资源的 ReferenceInput 包装它。

<Filter>
    ....
    <ReferenceInput
        source="status"
        reference="yourResource"
        filterToQuery={searchText => ({ status: searchText })}
    >
        <AutocompleteInput label="Status" optionText="status" />
    </ReferenceInput>
<Filter/>