根据复选框将输入框值添加到现有对象

时间:2019-05-30 21:43:26

标签: javascript reactjs

我有一个通过api调用呈现的数据表。它显示初始对象的4个值。我主要关心name的值,因为这在稍后的发布请求中很重要。

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

  "selectedFields": {
    "id" : {}
  }

效果很好。但是,我添加了3个与每个name相关联的输入框。输入是lengthTypesizemaxArrayElements,它们当然是用户可选的。 我遇到的麻烦是将这些值添加回该对象,使其看起来像:

  "selectedFields": {
    "id": {
       lengthType: Variable,
       size: 1,
       maxArrayElements: 1
    },
    "price": {
       lengthType: Fixed,
       size: 10,
       maxArrayElements: 1
    }
  }

如何将这3个值添加回已创建的name对象中,使其看起来像上面的示例?

我不想张贴代码墙,所以我要发布复选框功能,该功能处理使用适当选择的selectedFields创建names对象。我怀疑应该以某种方式在此处添加输入值,但是我不确定。

 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
      );
    }
  );
}

};

您必须首先选择下拉菜单才能查看数据。

CodeSandbox link here

1 个答案:

答案 0 :(得分:2)

答案

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


Index.js中的处理程序

您的change事件处理程序不会在寻找对象的名称来确定它是否存在。如果要将其添加到指定的子对象,则最好确保它在那里。

我们调整处理程序以在特定对象上使用对象名称和带有object.assign的setState:

note :由于lengthType没有name属性,因此我们仅向其提供一个字符串。 e.currentTarget将提供选项范围,而不是根Dropdown元素,因此即使向该组件提供name属性也不允许我们使用e.currentTarget.name-您可能想要如果您希望使用其他内容,请咨询Semantic UI documentation。我对其进行了快速扫描,但不想对其进行深入研究。

  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属性,该属性将接收事件并将其传递给处理程序函数 with 您的对象名称:

      <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>

一旦对这些内容进行了调整,在选中之后,代码将更新子对象上的指定属性。


最后的提示:

如果您先取消选中,然后选中该框,则我没有调整它来保存以前的状态。您的问题中未指定该参数,我也不想做假设。


代码沙箱:

调整后的代码沙箱:https://codesandbox.io/s/createqueryschema-table-rewrite-bwvo4?fontsize=14


其他建议:

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

  • 在加载复选框后,您将从checkbox文件中提供Index.js函数。在您的组件中简称为box。我建议在从父级传递到子级时,保持属性名称和状态等同。

  • 上面的checkbox函数从子级获取道具并将其传递给父级。在这里,您可以将收集的数据传递到父级的缓存,本地/会话存储或任何您想对数据进行的操作。您可以改为编写代码,以达到以下效果:如果在将输入处理程序称为 do 保存时选中了此复选框,但我想说这可能是在render上最好的选择,因为屏幕无论如何都在不断更新,并且您拥有checkbox功能,目前可以随时传递道具。 这是首选项,因此是您的通话


祝你好运!希望这会有所帮助!