提问人:Ping 提问时间:3/23/2021 最后编辑:LoicTheAztecPing 更新时间:2/16/2023 访问量:1687
WooCommerce 使用 Ajax 将多个商品添加到购物车
WooCommerce Adding multiple items to the cart with Ajax
问:
我使用最新版本的 Wordpress 和 Woocommerce。我有一些 JavaScript 可以遍历 class 的 DOM 元素并从带有 class 的元素中获取属性,并将该项目添加到购物车中:.selectable
product_id
.selected
// selects the elements
$('.next').on('click', function() {
var parent = $(this).closest('.panel');
var selectables = parent.children('.option.selectable.selected');
$(selectables).each(function() {
var product = $(this).attr('product');
add_to_cart(product, 1);
});
}
// add to cart AJAX
function add_to_cart(product_id, qty) {
$.ajax({
type: "POST",
url: base_url + '/wp-admin/admin-ajax.php',
data: {action : 'cl_add_to_cart', 'product_id': product_id, 'qty': qty},
success : function(response) {
console.log(response);
}
});
}
我在函数.php中有一个PHP函数
add_action('wp_ajax_cl_add_to_cart', 'cl_add_to_cart');
add_action('wp_ajax_nopriv_cl_add_to_cart', 'cl_add_to_cart');
function cl_add_to_cart() {
global $woocommerce;
$product_id = trim($_POST['product_id']);
$qty = !empty($_POST['qty']) ? trim($_POST['qty']) : 1;
$added = WC()->cart->add_to_cart($product_id, $qty);
echo json_encode($added);
}
AJAX 调用很好地击中了 PHP 函数 - 我可以回显$added这给了我一个哈希值。如果我在可选变量中有两个或更多项目,它们都会命中 PHP 函数(我得到两个哈希值),但只有第一个被添加到购物车中。
我一辈子都想不通为什么。有什么想法吗?
答:
最好使用 Ajax 一次性发送所有要添加的项目,而不是在多个 Ajax 请求中单独发送它们,这样会更轻、更有效。
您需要确保它按预期工作。$(selectables).each(function() { // ... });
以下命令将为单击事件发送唯一的 Ajax 请求。
jQuery 代码
// Multi Ajax adda to cart
function multiAddToCart( productsData ) {
$.ajax({
url: base_url + '/wp-admin/admin-ajax.php',
type: 'POST',
dataType: 'JSON',
data: {
'action': 'multi_add_to_cart',
'items' : Object.assign({}, productsData)
},
success : function(response) {
$(document.body).trigger('wc_fragment_refresh'); // Refresh cart fragments
console.log(response);
},
error : function(error) {
console.log(error);
}
});
}
$('.next').on('click', function() {
var productsData = [];
var parent = $(this).closest('.panel');
var selectables = parent.children('.option.selectable.selected');
$(selectables).each(function() {
var productId = $(this).attr('product');
productsData.push({'id': productId, 'qty': 1});
});
// Check the data before (number of items found)
console.log(productsData);
multiAddToCart( productsData );
});
php 接收器函数:
add_action('wp_ajax_multi_add_to_cart', 'multi_ajax_add_to_cart');
add_action('wp_ajax_nopriv_multi_add_to_cart', 'multi_ajax_add_to_cart');
function multi_ajax_add_to_cart() {
if (isset($_POST['items']) ) {
$item_keys = array();
foreach( $_POST['items'] as $item ) {
if( isset($item['id']) ) {
$item_qty = isset($item['qty']) && $item['qty'] > 1 ? $item['qty'] : 1;
$item_keys[] = WC()->cart->add_to_cart($item['id'], $item_qty);
}
}
echo json_encode($item_keys); // Send back cart item keys
}
die();
}
代码进入活动子主题(或活动主题)的函数.php文件。经过测试并有效。
它应该可以一次添加所有项目。
评论
主要答案并没有真正解决根本问题。此外,并不总是可以同时添加产品。您可能有一个订单,用户可以在其中快速单击多个不同的项目。
问题来了:
WooCommerce 添加到购物车功能通过将变量设置为特定项目来工作。$this->cart_contents
在 AJAX 中使用时会出现此问题,因为多个此类add_to_cart函数同时运行。发生的情况是,一个函数将在前一个函数启动但未完成之后启动。WC()->cart->add_to_cart()
结果是第二个函数设置购物车内容,而不知道它缺少上一个函数刚刚添加的产品。
现在的解决方案是:让 javascript 等到上一个函数用递归函数完成:
(这段代码并不完整,它只是说明了这个想法):
add_cart_clear = 'yes';
function order_form_add(datavar, qty){
if (add_cart_clear === 'yes'){ // proceed only if clear
add_cart_clear = 'no'; // new function started, not clear
$.post(ajaxurl, data, function(response){ // function ended, it's clear again
add_cart_clear = 'yes';
});
} else {
setTimeout(function(){
order_form_add(data, qty); // if not ready, wait 100ms and try again
}, 100);
}
}
评论