如何从对象中添加选择选项

Posted

技术标签:

【中文标题】如何从对象中添加选择选项【英文标题】:How do I add select options from an object 【发布时间】:2021-12-13 04:57:31 【问题描述】:

我正在尝试根据我拥有的对象创建一个下拉列表。我想不出一种不完全复杂的方法,而且我提出的解决方案也不起作用。我是反应和***的新手,所以我不确定只是征求意见是否可以。如果不是,请原谅我。我正在用 React 构建它。有没有办法做到这一点,我错过了。如果您不应该在这里寻求帮助,再次抱歉

我已经创建了如下组件

const HardwearForm = (isActive, Products, outputObj, setOutputObj) => 

const handleSelect = e => 
    let newParentNode = e.target;
    let selectedNumber = newParentNode.options.selectedIndex;
    let choice = newParentNode.options[selectedNumber].value;               
    setOutputObj(outputObj[newParentNode.id] = choice);        
    console.log(outputObj)        
        

useEffect(() =>  
    let parentNode = document.getElementById("make");
    Object.keys(Products[isActive]["hardwear"]).forEach(key =>             
    let newOption = document.createElement('option');
    newOption.value = key;
    newOption.innerText = key;
    parentNode.appendChild(newOption);
    )
,[isActive, Products]); 

return (
    <div>
    <select name="make" className="hardwear" id="make" onChange=handleSelect>
        <option value="*">Manufacturer</option>
    </select>
    <select name="model" className="hardwear" id="model"></select>
    isActive === "handset"|| isActive==="tablet"?
    <>
    <select name="storage" className="hardwear" id="storage""></select></>:""
    isActive === "handset"|| isActive==="tablet" ||isActive=== "watch"?
    <>
    <select name="color" className="hardwear"></select></>:""
    isActive === "handset"|| isActive==="watch"?
    <>
)

基本的想法是我有一个带有几个按钮的菜单。这些按钮更新 isActive 状态,然后导致 useEffect 运行并使用选项填充第一个选择。这很好用。然后我进行了设置,因此一旦选择了第一个下拉列表中的选择,它就会触发 handleSelect 函数,该函数对下一个选择执行相同的操作。我设置了一个空对象来存储所有选项。 setOutputObj(outputObj[newParentNode.id] = 选择);和该对象的键值对。问题是,如果您随后尝试更改所选选项,则会出错“TypeError: Cannot create property 'make' on string 'Huawei'”。

这是我正在使用的日期结构的示例。

"Fairphone": 
        "3+": 
            "color": ["Black"],
            "storage": ["64GB"], 
        
    ,
    "Doro": 
        "8050": 
            "color": ["Black"],
            "storage": ["16GB"], 
        
    ,
    "Mobiwire": 
        "Smart N12": 
            "color": ["Dark Metallic Blue"],
            "storage": ["16GB"], 
        
    ,

【问题讨论】:

可以修改数据结构还是必须坚持的东西? 目前我可以随意构建数据。我有 6 种产品类型的列表。上面是手机,分为制造商、型号、存储容量选项和颜色。重组结构会有帮助吗? 【参考方案1】:

我对你的数据结构和你想要实现的目标有点困惑,但总的来说,动态设置来自对象的选择输入的选项我认为最好使用 array.map 而不是尝试直接修改 DOM。

例如: https://codesandbox.io/s/compassionate-buck-8sir5?file=/src/App.js

import  useState  from "react";
import "./styles.css";

const productsByManufacturers = 
  "Manufacturer 1": ["product 1", "product 2", "product 3"],
  "Manufacturer 2": ["product 4", "product 5"]
;

export default function App() 
  const [manufacturer, setManufacturer] = useState("");

  return (
    <div className="App" style= display: "flex", flexDirection: "column" >
      <label>Select Manufacturer:</label>
      <select
        value=manufacturer
        onChange=(e) => setManufacturer(e.target.value)
      >
        <option value="" disabled>
          Select a manufacturer
        </option>
        Object.keys(productsByManufacturers).map((manufacturer) => (
          <option value=manufacturer>manufacturer</option>
        ))
      </select>

      manufacturer !== "" && (
        <div
          style= marginTop: 20, display: "flex", flexDirection: "column" 
        >
          <label>Select Product:</label>
          <select>
            productsByManufacturers[manufacturer].map((product) => (
              <option value=product>product</option>
            ))
          </select>
        </div>
      )
    </div>
  );


【讨论】:

我之所以将其结构化,是因为我希望第一个下拉列表提供第一个分支选项,然后仅根据该分支中可用的内容打开其他选项。我试图避免用户能够选择在他们选择的范围内不可用的存储选项。如果我按照您上面的方式进行操作,那么如果我理解您的话,它仅适用于两个级别的可能性。一个制造商和一个产品。我真的需要颜色和存储选项这两个进一步的选项 它只适用于两个级别,因为我的虚拟数据中只有两个级别。如果您愿意,您可以以相同的方式添加更多图层。我认为重组数据会更好。您应该有一个产品对象数组。每个产品对象都应该有每个属性的键。例如[名称:XXX,制造商:XXX,颜色:[XXX,XXX],存储:[XXX,XXX],...更多产品]。我认为使用 array.filter 过滤您的产品会更容易 你的意思是这样的:[ manufacturer : "Fairphone", model : "3+", colors: ["black", "green", "red"], storage : ["128GB" , "256GB"] , manufacturer : "Apple", model : "iphone 12 pro max"", colors: ["black", "green", "red"], storage : ["128GB" , "256GB"] , ]我不知道这会有什么帮助。你看,我希望第一个下拉列表始终填充所有制造商选项,然后如果他们选择 Apple,所有苹果型号都会显示在下一个下拉列表中。然后,当他们选择模型时,下一个下拉菜单仅显示该模型的存储选项。

以上是关于如何从对象中添加选择选项的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应选择下拉菜单中的选项下添加子选项?

如何从所有选择选项中获取总数据价格(总计每个选择)

如何使用淘汰赛从复杂对象的选择选项中设置值?

没有添加委托的选项

如何从select2多选中的选项列表中删除选定的选项并按选择的顺序显示选定的选项

如何从选择菜单中删除选项?