Javascript 基于复选框向现有对象添加输入框值

Javascript 基于复选框向现有对象添加输入框值,javascript,reactjs,Javascript,Reactjs,我有一个通过api调用呈现的数据表。它显示来自初始对象的4个值。我主要关心名称值,因为这是后期post请求中的重要内容 表中的每一行都有一个复选框。选中复选框(true)时,与该复选框关联的名称将作为对象添加到名为selectedFields的对象中。例如,如果我选中名为id的复选框,它将创建一个对象存储,如: "selectedFields": { "id" : {} } 这很好用。但是,我添加了3个与每个名称关联的输入框。输入为lengthType,size,maxaray

我有一个通过api调用呈现的数据表。它显示来自初始对象的4个值。我主要关心
名称
值,因为这是后期post请求中的重要内容

表中的每一行都有一个复选框。选中复选框(
true
)时,与该复选框关联的名称将作为对象添加到名为
selectedFields
的对象中。例如,如果我选中名为
id
的复选框,它将创建一个对象存储,如:

  "selectedFields": {
    "id" : {}
  }
这很好用。但是,我添加了3个与每个
名称关联的输入框。输入为
lengthType
size
maxarayelements
,这些当然是用户可选择的。 我遇到的问题是将这些值添加回对象,使其看起来像:

  "selectedFields": {
    "id": {
       lengthType: Variable,
       size: 1,
       maxArrayElements: 1
    },
    "price": {
       lengthType: Fixed,
       size: 10,
       maxArrayElements: 1
    }
  }
如何将这3个值添加回创建的
name
对象,使其看起来像上面的示例

我不想发布代码墙,所以我发布了checkbox函数,该函数处理使用适当的选定名称创建
selectedFields
对象。我怀疑输入值应该以某种方式添加到这里,但我不确定

 checkbox = ({ name, isChecked }) => {
//handle check box of each fieldName
const obj = this.state.fieldNames.find(field => field.name === name);
if (isChecked === true) {
  //checked conditional
  this.setState(
    {
      selectedFields: {
        ...this.state.selectedFields,
        [name]: {
          ...obj
        }
      }
    },
    () => {
      console.log(
        "callback in  isChecked if conditional",
        this.state.selectedFields
      );
    }
  );
} else {
  const newSelectedFields = this.state.selectedFields;
  delete newSelectedFields[name];
  this.setState(
    {
      selectedFields: newSelectedFields
    },
    () => {
      console.log(
        `box unchecked, deleted from object --->`,
        this.state.selectedFields
      );
    }
  );
}
})

您必须进行第一次下拉选择才能查看数据

答案 您需要更改一些内容,因为没有任何内容说明在根状态对象之外向何处分配新状态


Index.js中的处理程序:

更改事件的处理程序没有查找对象的名称来确定它是否存在。如果要将它添加到指定的子对象,最好确保它在那里

我们调整处理程序以获取对象名称,并使用
对象设置state。如果该特定对象存在,则为其分配

注意:由于
lengthType
没有
name
属性,因此我们仅为其提供一个字符串
e.currentTarget
将提供选项范围,而不是根
下拉列表
元素,因此即使为该组件提供
name
属性,也不允许我们使用
e.currentTarget.name
-如果您喜欢其他内容,您可能需要咨询。我快速扫描了一下,但不想深入研究

  handleChange = (e, obj_name) => {
    if (this.state.selectedFields[obj_name]) {
      let selectedFields = Object.assign({}, this.state.selectedFields);
      selectedFields[obj_name] = Object.assign(
        this.state.selectedFields[obj_name],
        { [e.target.name]: e.target.value }
      );
      this.setState({ selectedFields });
    }
  };

  onLengthTypeChange = (e, obj_name) => {
    if (this.state.selectedFields[obj_name]) {
      let selectedFields = Object.assign({}, this.state.selectedFields);
      selectedFields[obj_name] = Object.assign(
        this.state.selectedFields[obj_name],
        { lengthType: e.currentTarget.textContent }
      );
      this.setState({ selectedFields });
    }
  };
当然,如果您不调整组件上的
onChange
事件,使它们除了发送事件对象外,还发送对象名称,则上述操作将不起作用


组件文件中的处理程序:

注意:这很奇怪,因为在你的
Index.js
文件中,你似乎用
lengthType
做了一半,但你没有传递额外的数据。您不能简单地将参数传递给处理程序-要使其正常工作,您需要将匿名函数传递给
onChange
属性,该属性将接受事件并将其传递给处理程序函数,对象名为:

      <Table.Cell>
        <Dropdown
          placeholder="Pick a length Type:"
          clearable
          selection
          search
          fluid
          noResultsMessage="Please search again"
          label="lengthType"
          multiple={false}
          options={lengthTypeOptions}
          header="Choose a Length Type"
          onChange={e => onLengthTypeChange(e, name)}
          value={lengthType}
          required
        />
      </Table.Cell>
      <Table.Cell>
        <Input
          onChange={e => handleChange(e, name)}
          value={this.state.size}
          type="number"
          name="size"
          min="1"
          placeholder="1"
          required
        />
      </Table.Cell>
      <Table.Cell>
        <Input
          onChange={e => handleChange(e, name)}
          value={this.state.maxArrayElements}
          type="number"
          name="maxArrayElements"
          placeholder="1"
          min="1"
          max="100"
          required
        />
      </Table.Cell>

onLengthTypeChange(e,name)}
值={lengthType}
必修的
/>
handleChange(e,name)}
值={this.state.size}
type=“编号”
name=“size”
min=“1”
占位符=“1”
必修的
/>
handleChange(e,name)}
值={this.state.maxArrayElements}
type=“编号”
name=“maxArrayElements”
占位符=“1”
min=“1”
max=“100”
必修的
/>
调整这些内容后,在选中相应的复选框后,代码将更新子对象上的指定属性


最后说明: 如果您取消选中,然后选中复选框,我没有将其调整为保存以前的状态。你的问题中没有具体说明,我不想做假设


代码沙盒: 调整后的代码沙箱:


其他建议:
  • 在初始状态下,您的
    selectedFields
    被声明为
    数组
    ,然后当选中任何复选框时,它会立即变成
    对象
    。我建议不要这样做在运行应用程序的过程中更改属性上的数据类型非常麻烦。

  • 加载复选框时,您可以从
    Index.js
    文件中提供一个
    checkbox
    函数。这在组件中被简单地称为
    box
    。我建议在从父代传递给子代时,保持属性和状态的名称相同。如果有必要的话,其他人更容易进入并保持自己的理智,更不用说保持自己的理智了

  • 上面的
    复选框
    函数从子级获取道具并将其传递给父级。这将是将收集的数据传递到父级缓存、本地/会话存储或任何您想对数据执行的操作的地方。相反,您可以编写这样的代码:如果在调用输入处理程序时选中复选框,则执行保存操作-但我想说,最好是在
    render
    上进行保存,因为屏幕始终在不断更新,并且您当前有
    复选框
    功能随时传递道具这是首选项,因此由您决定



祝你好运!希望这有帮助

你触及了我正在努力/质疑的每一个部分。非常感谢。根据您的第一个建议,我实际上刚刚发现
selectedFields
需要是一个对象数组(选中的复选框)<代码>“selectedFields”:[{“name”:“nameOne”,“lengthType”:“fixed”。.etc},{“name”:“nameTwo”。.etc}]
我在获取
selectedFi时遇到了一些问题