首页 > 解决方案 > 根据属性选择查找变体 ID

问题描述

我有一个以下产品对象,它有变体,变体依赖于属性。例如,产品 A 有以下变体

  1. 尺码 M,颜色为黑色、灰色
  2. 尺寸 L,颜色为黑色

以对象格式显示它是这样的

{
  "variants": [{
      "id": "1",
      "name": "Variant name 1",
      "price": null,
      "stock": 2,
      "variantAttributes": [{
          "attribute": {
            "id": "2",
            "name": "Size"
          },
          "values": [{
            "id": "1",
            "name": "Medium",
            "value": "M"
          }]
        },
        {
          "attribute": {
            "id": "3",
            "name": "Color"
          },
          "values": [{
            "id": "3",
            "name": "Black",
            "value": "#000"
          }]
        }
      ]
    },
    {
      "id": "2",
      "name": "Variant name 2",
      "price": null,
      "stock": 2,
      "variantAttributes": [{
          "attribute": {
            "id": "2",
            "name": "Size"
          },
          "values": [{
            "id": "2",
            "name": "Large",
            "value": "L"
          }]
        },
        {
          "attribute": {
            "id": "3",
            "name": "Color"
          },
          "values": [{
            "id": "3",
            "name": "Black",
            "value": "#000"
          }]
        }
      ]
    }
  ]
}

现在的问题是我找不到用户选择的变体 ID。例如,如果用户选择尺寸为“M”且颜色为“黑色”的产品,则根据我在对象中共享的示例,变体 ID 应为“1”。

这是用户界面

在此处输入图像描述

为了显示属性,这就是我所做的

function productVariantAttributesPicker(productVariantsAttributes, setSizeGuideOpen, handleColorChange,handleSizeChange,rest) {
  return Object.keys(productVariantsAttributes).map(
    (productVariantsAttributeId,i) => {
      const productVariantsAttribute =
        productVariantsAttributes[productVariantsAttributeId];
      const { slug, id } = productVariantsAttribute.attribute;
      if (slug === "color") {
        return <ColorPicker key={i} colorVariant={productVariantsAttributes[id]} handleColorChange={handleColorChange} selectedColor={rest.selectedColor}/>;
      }
      if (slug === "size") {
        return (
          <SizePicker
            key={i}
            sizeVariant={productVariantsAttributes[id]}
            // setDisplaySizesOpen={rest.setDisplaySizesOpen}
            setSizeGuideOpen={setSizeGuideOpen}
            handleSizeChange={handleSizeChange}
            selectedSize={rest.selectedSize}
          />
        );
      }
    }
  );
}

<div>
  {productVariantAttributesPicker(
    variants,
    setSizeGuideOpen,
    handleColorChange,
    handleSizeChange,
    {selectedSize,selectedColor}
  )}
  {selectedColor && selectedSize && (
    <div>
      <AddToCart handleAddToCart={handleAddToCart}></AddToCart>
    </div>
  )}
</div>

任何人都可以帮助我根据用户选择的属性找到变体 id,其中所选属性采用这种形式?

const selected_size = {id: "1", name: "Medium", value: "M"}
const selected_color = {id: "3", name: "Black", value: "#000""}

标签: javascriptreactjs

解决方案


如果我理解正确,您需要找到一个同时variantAttributes包含selected_size和的变体selected_color

如果是这样,逻辑应该是这样的:

function hasAttr(variantAttribute, id, value) {
  return variantAttribute.find(
    variant => {
      return variant.values.some((attrValue) => (attrValue.id === id && attrValue.value === value))
    }
  );
}
const variant = variants.find(
  (variant) => {
    return hasAttr(variant.variantAttributes, selected_size.id, selected_size.value) &&
      hasAttr(variant.variantAttributes, selected_color.id, selected_color.value);
  }
);

有更通用的方法,但我将示例简化为更清晰。

演示

const variants = [{
    id: '1',
    name: 'Variant name 1',
    price: null,
    stock: 2,
    variantAttributes: [{
        attribute: {
          id: '2',
          name: 'Size',
        },
        values: [{
          id: '1',
          name: 'Medium',
          value: 'M',
        }, ],
      },
      {
        attribute: {
          id: '3',
          name: 'Color',
        },
        values: [{
          id: '3',
          name: 'Black',
          value: '#000',
        }, ],
      },
    ],
  },
  {
    id: '2',
    name: 'Variant name 2',
    price: null,
    stock: 2,
    variantAttributes: [{
        attribute: {
          id: '2',
          name: 'Size',
        },
        values: [{
          id: '2',
          name: 'Large',
          value: 'L',
        }, ],
      },
      {
        attribute: {
          id: '3',
          name: 'Color',
        },
        values: [{
          id: '3',
          name: 'Black',
          value: '#000',
        }, ],
      },
    ],
  },
];

const selected_size = {
  id: '1',
  name: 'Medium',
  value: 'M'
};
const selected_color = {
  id: '3',
  name: 'Black',
  value: '#000'
};

function hasAttr(variantAttribute, id, value) {
  return variantAttribute.find(
    variant => {
      return variant.values.some((attrValue) => (attrValue.id === id && attrValue.value === value))
    }
  );
}
const variant = variants.find(
  (variant) => {
    return hasAttr(variant.variantAttributes, selected_size.id, selected_size.value) &&
      hasAttr(variant.variantAttributes, selected_color.id, selected_color.value);
  }
);

console.log(variant);


推荐阅读