You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopify Storefront API GraphQL如何获取选中产品的特定数据

实现方案

你的现有代码存在4个核心问题,会导致无法正确匹配选中产品、拿不到元字段数据:

  • 初始查询产品列表的GraphQL语句没有请求metafields字段,接口不会返回元字段数据
  • 生成下拉选项时<option>标签闭合错误,写成了开标签<option>会导致DOM结构异常
  • 选择事件中获取选中值的逻辑错误:$(this).find('option').val()永远取第一个选项的值,无法拿到当前选中项
  • 选择事件触发后遍历全量产品追加所有产品标题,既没有匹配选中项,也没有清空上一次选择的渲染结果

方案1:首屏拉取全量产品+元字段(适合产品数≤250的场景)

你当前设置的products(first:250)刚好是Shopify Storefront API单请求拉取产品的上限,产品量不大的话可以首屏直接把所有产品的元字段一起拉回,选中时直接从本地缓存的接口返回值里匹配即可,不需要额外发请求。
首先修改产品查询的GraphQL语句,补充metafields字段,注意要指定你需要的元字段命名空间(比如Shopify后台自定义元字段默认命名空间是custom):

{ 
  products(first: 250) { 
    edges { 
      node { 
        id 
        handle 
        title 
        metafields(first: 20, namespace: "custom") {
          edges {
            node {
              key
              value
              type
            }
          }
        }
      } 
    } 
  } 
}

如果你需要拉取其他命名空间的元字段,替换namespace的值即可;不指定namespace会返回当前访问令牌有权限读取的所有元字段。

修正后的完整代码如下:

function apiCall(productQuery) { 
    return fetch('https://store//api/2022-04/graphql.json', 
        { 
            method: 'POST', 
            headers: { 
                'Content-Type': 'application/graphql', 
                'X-Shopify-Storefront-Access-Token': "xxx" 
            }, 
            body: productQuery 
        }
    )
    .then(response => response.json()); 
}

function getProducts() { 
    const productQuery = `{ 
        products(first: 250) { 
            edges { 
                node { 
                    id 
                    handle 
                    title 
                    metafields(first: 20, namespace: "custom") {
                        edges {
                            node {
                                key
                                value
                                type
                            }
                        }
                    }
                } 
            } 
        } 
    }`; 
    return apiCall(productQuery); 
}

$(document).ready(function() { 
    const product_selector_container = $('.product_selector_container'); 
    getProducts().then(response => { 
        product_selector_container.prepend("<select name='product_compatibility_selector' id='product_compatibility_selector'></select>"); 
        const productSelect = $('#product_compatibility_selector');
        const productSelectResult = $("#product_compatibility_result");
        response.data.products.edges.forEach(product => { 
            // 修正option标签闭合错误
            const optionValues = `<option value="${product.node.handle}">${product.node.title}</option>`; 
            productSelect.append(optionValues); 
        }); 
        
        $("#product_compatibility_selector").on('change', function() {
            // 正确获取当前选中项的标题和handle
            const selectedTitle = $(this).find('option:selected').text();
            const selectedHandle = $(this).val();
            $(".chosen_product_title").text(selectedTitle);
            
            // 匹配当前选中的产品
            const selectedProductEdge = response.data.products.edges.find(edge => edge.node.handle === selectedHandle);
            // 清空上一次渲染的结果
            productSelectResult.empty();
            if (!selectedProductEdge) return;
            const selectedProduct = selectedProductEdge.node;
            
            // 渲染元字段,可按需调整展示格式
            let metafieldsHtml = '<ul class="product-metafields">';
            selectedProduct.metafields.edges.forEach(metafieldEdge => {
                const mf = metafieldEdge.node;
                metafieldsHtml += `<li><strong>${mf.key}:</strong> ${mf.value}</li>`
            })
            metafieldsHtml += '</ul>';
            productSelectResult.append(metafieldsHtml);
        });
    });  
}); 

方案2:选中后单独请求单个产品元字段(适合产品量大的场景)

如果产品数多、元字段数据量大,首屏全量拉取会拖慢加载速度,可以不在初始查询中携带metafields字段,等用户选中产品时,单独发请求查询对应产品的元字段即可。
单个产品按handle查询的GraphQL示例:

{
  productByHandle(handle: "选中产品的handle值") {
    title
    metafields(first: 20, namespace: "custom") {
      edges {
        node {
          key
          value
          type
        }
      }
    }
  }
}

选中事件触发时拿到选中项的handle,调用apiCall传入上述查询语句,拿到返回结果后渲染到页面即可。

内容的提问来源于stack exchange,提问作者Mathijs Delva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 03:54:22