动态生成表单可路由至控制器但AJAX数据无法提交问题
解决动态添加商品的“立即购买”按钮报错问题
我帮你梳理下问题根源,以及对应的解决方案:
问题根源
你的核心问题出在动态生成的DOM元素没有绑定事件,以及后端缺少空值校验:
- 页面加载时绑定的
$('form.buy-product-form').on('submit', ...)只对当时已经存在的表单生效,后来动态添加的商品表单没有触发这个AJAX事件,导致按钮点击时表单直接走默认的POST提交。 - 默认提交的表单里没有传递
id参数(你的AJAX里手动传了{'id': product_id},但默认提交不会带这个),所以后端$request->id是空值,执行Product::where('id', $product_id)->first()得到的$product是null,自然就会报Trying to get property 'quantity_available' of non-object的错误。
解决方案
1. 用事件委托绑定动态元素的提交事件
把事件监听改成委托给静态的父元素(比如你的.content容器,因为动态商品是append到这里的),这样后续添加的表单也能触发AJAX:
// 替换原来的事件监听代码 $('.content').on('submit', 'form.buy-product-form', function(e) { e.preventDefault(); // 阻止默认表单提交 var product_id = $(this).closest('.product').attr("id"); var element = $(this).closest('.product'); // 从当前表单中获取CSRF token,确保AJAX请求通过Laravel的CSRF校验 var csrfToken = $('input[name="_token"]', this).val(); $.ajax({ url: $(this).attr('action'), type: 'POST', data: { 'id': product_id, '_token': csrfToken // 必须带上CSRF token }, dataType: 'json', success: function (data) { if(data.valid_funds) { updateSideBarContent(data.player_capital, data.total_price, data.player_utility, data.marginal_utility, data.purchases); } else { window.alert("You do not have enough funds!"); } }, error: function (xhr) { // 可以根据后端返回的错误信息提示用户 var errorMsg = xhr.responseJSON?.error || "Error, product may no longer exist. Transaction cancelled!"; window.alert(errorMsg); $(element).css('background-color', 'red'); $(element).fadeOut(100, function() { removeElement(element); }); } }); });
2. 后端增加空值与存在性校验
在UserController的buyProduct方法里,先校验参数和商品是否存在,避免空对象报错:
public function buyProduct(Request $request){ // 先验证product_id是否存在 $product_id = $request->id; if(!$product_id) { return response()->json(['error' => 'Product ID is required'], 400); } $player = Player::where('user_id', Auth::user()->id)->first(); $product = Product::where('id', $product_id)->first(); // 检查商品是否存在 if(!$product) { return response()->json(['error' => 'Product not found'], 404); } // 后续逻辑正常执行 $totalPrice = $product->quantity_available * $product->price; // ... 你的其他代码 }
3. 额外检查:确保动态生成的ID正确
确认newProductData.id是有效的商品ID,避免生成的商品元素ID或表单action中的ID错误,导致后端查不到商品。
这样调整后,动态添加的商品点击“立即购买”时会正确触发AJAX请求,后端也能收到正确的商品ID,同时避免了空对象报错的问题。
内容的提问来源于stack exchange,提问作者Hamish Gibson
相关产品推荐
相关产品推荐

