React query builder 问题:在向查询添加规则时是否可以禁用字段选项

React query builder question: Is there a way to disable a field option when adding rules to a query

我正在尝试创建一个采用初始字段(种类、属性 和 属性 值)的查询。这部分很简单。但是对于每个额外的查询 option/rule 我想禁用“种类”选项并且只保留“属性”和“属性 值”因为数据库只接受一种“种类”但多个“属性”和“属性 值”。 这是图书馆:https://github.com/react-querybuilder/react-querybuilder#usage

React-Query-Builder

我想我已经在 this codesandbox 中实现了您想要的效果。我不得不使用很多自定义组件,但它们都退回到默认组件,它们自己的逻辑相对较少——根据 level 属性隐藏它们自己或者只是总是隐藏。

相关代码如下:

import { useState } from "react";
import QueryBuilder, {
  ActionElement,
  ActionProps,
  ActionWithRulesProps,
  FieldSelectorProps,
  formatQuery,
  OperatorSelectorProps,
  RuleGroupType,
  RuleType,
  ValueEditor,
  ValueEditorProps,
  ValueSelector
} from "react-querybuilder";
import "react-querybuilder/dist/query-builder.css";

const fields = [
  { name: "first_name", label: "First Name" },
  { name: "email", label: "Email" },
  { name: "last_name", label: "Last Name" }
];

const defaultQuery: RuleGroupType = {
  id: "root",
  combinator: "and",
  rules: [
    {
      field: "last_name",
      operator: "=",
      value: ""
    },
    {
      id: "ruleGroup",
      combinator: "and",
      rules: []
    }
  ]
};

const addRuleAction = (props: ActionWithRulesProps) => {
  if (props.level === 0) {
    return null;
  }
  return <ActionElement {...props} />;
};

const addGroupAction = () => null;

const removeGroupAction = () => null;

const removeRuleAction = (props: ActionProps) => {
  if (props.level === 0) {
    return null;
  }
  return <ActionElement {...props} />;
};

const combinatorSelector = () => null;

const fieldSelector = (props: FieldSelectorProps) => {
  if (props.level > 0) {
    return null;
  }
  return <ValueSelector {...props} />;
};

const operatorSelector = (props: OperatorSelectorProps) => {
  if (props.level === 0) {
    return null;
  }
  return <ValueSelector {...props} />;
};

const valueEditor = (props: ValueEditorProps) => {
  if (props.level === 0) {
    return null;
  }
  return <ValueEditor {...props} />;
};

export default function App() {
  const [query, setQuery] = useState<RuleGroupType>(defaultQuery);

  const onQueryChange = (q: RuleGroupType) => {
    const f = (q.rules[0] as RuleType).field;
    const newQuery = {
      ...q,
      rules: [
        q.rules[0],
        {
          ...q.rules[1],
          rules: (q.rules[1] as RuleGroupType).rules.map((r) => ({
            ...r,
            field: f
          }))
        }
      ]
    };

    setQuery(newQuery);
  };

  return (
    <>
      <QueryBuilder
        fields={fields}
        onQueryChange={onQueryChange}
        query={query}
        controlElements={{
          addRuleAction,
          addGroupAction,
          removeGroupAction,
          combinatorSelector,
          operatorSelector,
          removeRuleAction,
          fieldSelector,
          valueEditor
        }}
        getDefaultField={() => "last_name"}
      />
      <h3>Output:</h3>
      <pre>{formatQuery(query)}</pre>
    </>
  );
}