BigCommerce Stencil主题:通过产品ID获取并整合产品信息
在BigCommerce Stencil主题中处理关联产品数据
1. 从GraphQL响应中提取产品数据
先写好明确请求所需字段的GraphQL查询,比如只获取名称、URL和首张图片:
query getProductById($productId: Int!) { productById(id: $productId) { name url images(first: 1) { edges { node { urlOriginal altText } } } } }
发送fetch请求后,按照GraphQL的返回层级提取数据,用可选链操作符避免字段缺失报错:
fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + '你的Storefront API令牌' // 替换为实际令牌 }, body: JSON.stringify({ query: 'query getProductById($productId: Int!) { productById(id: $productId) { name url images(first: 1) { edges { node { urlOriginal altText } } } } }', variables: { productId: '关联产品ID' } // 替换为自定义字段存的ID }) }) .then(response => response.json()) .then(data => { const product = data.data.productById; if (!product) return; // 拆解需要的字段 const productName = product.name; const productUrl = product.url; const firstImage = product.images.edges[0]?.node; const imageUrl = firstImage?.urlOriginal; const imageAlt = firstImage?.altText || productName; // 调用渲染函数处理HTML renderProduct(productName, productUrl, imageUrl, imageAlt); });
核心是对应GraphQL查询的返回结构,data.data.productById是产品数据的根节点,逐层向下提取即可。
2. 高效整合HTML结构
放弃手动创建DOM节点的方式,直接用ES6模板字符串拼接HTML结构,一次性插入DOM,减少重绘重排:
function renderProduct(name, url, imageUrl, imageAlt) { // 预定义HTML模板,可根据主题样式调整类名 const productHtml = ` <div class="associated-product"> <a href="${url}" class="product-link"> <img src="${imageUrl}" alt="${imageAlt}" class="product-image"> <h3 class="product-name">${name}</h3> </a> </div> `; // 插入到页面目标容器(需提前在模板中定义该容器) document.querySelector('.associated-products-container').insertAdjacentHTML('beforeend', productHtml); }
如果是批量处理多个关联产品ID,先收集所有产品数据再一次性渲染,性能更优:
// 假设自定义字段存的ID数组 const associatedProductIds = [123, 456, 789]; // 批量生成fetch请求 const productPromises = associatedProductIds.map(id => fetchSingleProduct(id)); Promise.all(productPromises) .then(products => { // 过滤掉不存在的产品 const validProducts = products.filter(p => p); // 一次性拼接所有产品的HTML const allProductsHtml = validProducts.map(product => ` <div class="associated-product"> <a href="${product.url}" class="product-link"> <img src="${product.imageUrl}" alt="${product.imageAlt}" class="product-image"> <h3 class="product-name">${product.name}</h3> </a> </div> `).join(''); // 一次性插入到容器 document.querySelector('.associated-products-container').innerHTML = allProductsHtml; }); // 封装单产品请求函数 function fetchSingleProduct(productId) { return fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + '你的Storefront API令牌' }, body: JSON.stringify({ query: 'query getProductById($productId: Int!) { productById(id: $productId) { name url images(first: 1) { edges { node { urlOriginal altText } } } } }', variables: { productId } }) }) .then(res => res.json()) .then(data => { const p = data.data.productById; if (!p) return null; return { name: p.name, url: p.url, imageUrl: p.images.edges[0]?.node.urlOriginal, imageAlt: p.images.edges[0]?.node.altText || p.name }; }); }
内容的提问来源于stack exchange,提问作者Jimil
相关产品推荐
相关产品推荐

