首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >基于复选框向现有对象添加输入框值

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

Stack Overflow用户
提问于 2019-05-31 05:43:26
回答 1查看 267关注 0票数 1

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

表中的每一行都有一个复选框。选中复选框(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对象中,使其看起来像上面的示例?

我不想发布一大堆代码,所以我发布了checkbox函数,该函数使用适当的选定names创建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
      );
    }
  );
}

};

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

CodeSandbox link here

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-31 06:53:19

回答

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

Index.js中的处理程序

change事件的处理程序不会通过查找对象的名称来确定它是否存在。如果你想把它添加到指定的子对象中,你最好确保它在那里。

我们调整处理程序以获取一个对象名,并在该特定对象上使用object.assign进行setState (如果存在):

注意:由于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属性,该属性将接受事件并将其传递给处理程序函数,并使用作为对象名:

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

一旦调整了这些内容,在相应的复选框为selected之后,代码将更新子对象上指定的属性。

最后注意事项:

我没有调整它来保存之前的状态,如果您取消选中,然后选中框。你的问题中没有具体说明,我不想做假设。

代码沙盒:

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

其他建议:

  • 在初始状态下,您的selectedFields被声明为Array,然后当选中任何复选框时,它会立即转换为Object。我建议不要这么做。在运行应用程序的过程中更改属性上的数据类型非常需要trouble.
  • When,如果加载了复选框,则会从Index.js文件中提供一个checkbox函数。在您的组件中,这被简单地称为box。我建议在从父级传递到子级时,保持属性和状态的名称相同。如果其他人不得不进来维护它,这要容易得多-更不用说更容易保持你自己的理智了。
  • 上面的checkbox函数从孩子那里获取道具,并将它们传递给父母。这将是将收集的数据传递到父级上的缓存、本地/会话存储或您想要对数据执行的任何操作的地方。相反,你可以编写这样的代码:如果在调用输入处理程序时选中了复选框,则执行保存-但我想说的是,在render上可能是最好的,因为屏幕无论如何都在不断更新,而且你现在有checkbox函数可以随时传递道具。这是你的偏好,所以这是你的call

祝好运!希望这能有所帮助!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56385991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档