首页 > 解决方案 > 有条件地创建字段对象的简单方法?

问题描述

我正在开发一个严重依赖数据输入的应用程序,因此我必须使用必需和非必需数据构造不同类型的对象,而非必需数据块是我的问题,因为这会导致很多额外的代码,我想知道是否有办法避免这种情况。

这里我有一个包含 6 个字段的表单(它只是一个示例,但我在应用程序的许多其他地方都有相同的情况),其中 2 个是必需的,其余的不是,我编写了这个函数来处理对象创建:

  const handleAddSupplier = (e) => {
    e.preventDefault();
    const formData = e.target.elements;

    const supplierData = {
      name: formData.name.value,
      companyId: formData.companyId.value,
      ...((formData.country.value || formData.city.value || formData.postalCode.value || formData.street.value) && {
        address: {
          ...(formData.country.value && { country: formData.country.value }),
          ...(formData.city.value && { city: formData.city.value }),
          ...(formData.postalCode.value && { postalCode: formData.postalCode.value }),
          ...(formData.street.value && { street: formData.street.value }),
        },
      }),
    };

    console.log(supplierData);
  };

它可以工作,但是在我看来它的代码太多了,我怀疑有一种更简单的方法可以做到这一点。

必须创建的对象的“签名”是:

{
  name: "",
  companyId: "",
  address: {
    country: "",
    city: "",
    postalCode: "",
    street: ""
  }
}

地址对象及其字段是完全可选的,所以如果地址的字段都不可用(即用户只输入必需的字段而没有其他内容),则根本不应该创建地址对象,即使是空对象也不行.

我的代码有效,我只是想看看是否还有其他更简单的方法。

编辑:我稍微解构了对象并为自己节省了一些写作,但是,如果我有 10 个非必填字段怎么办,我是否有条件地“或”它们全部 10 个?

const { name, companyId, country, city, postalCode, street } = e.target.elements;

const supplierData = {
  name: name.value,
  companyId: companyId.value,
  ...((country.value || city.value || postalCode.value || street.value) && {
    address: {
      ...(country.value && { country: country.value }),
      ...(city.value && { city: city.value }),
      ...(postalCode.value && { postalCode: postalCode.value }),
      ...(street.value && { street: street.value }),
    },
  }),
};

或者用另一种方式写同样的东西:

const {
  name: { value: name },
  companyId: { value: companyId },
  country: { value: country },
  city: { value: city },
  postalCode: { value: postalCode },
  street: { value: street },
} = e.target.elements;

const supplierData = {
  name: name,
  companyId: companyId,
  ...((country || city || postalCode || street) && {
    address: {
      ...(country && { country }),
      ...(city && { city }),
      ...(postalCode && { postalCode }),
      ...(street && { street }),
    },
  }),
};

所以这就引出了一个问题,这只是一个“选择你的毒药”的场景吗?例如最后一个场景,您在创建对象之前编写代码来解构和命名属性,然后在对象内部,代码更简单更易于阅读?

这让我想到了另一个问题,我正在寻找的优化,是否值得研究,或者坚持这些场景中的任何一个都可以?

标签: javascript

解决方案


你可以循环检查它们

function process(e) {
  let obj = {}
  for(let item of e.target.elements){
    if(item.value) obj[item.name]=item.value //should do proper check if it's can have valid falsy value, I leave it here for simplicity
  }
  console.log(obj)
}
<form onsubmit="process(event);return false;">
  <div>
    <label for=a>A: </label>
    <input type=text name=a>
  </div>
  <div>
    <label for=b>B: </label>
    <input type=text name=b>
  </div>
  <div>
    <button type="submit">OK</button>
  </div>
</form>



推荐阅读