Laravel中如何通过Ajax展示数据库存储的数据?
在Laravel中通过Ajax展示数据库更新后的购物车数据
你已经实现了通过Ajax将商品添加到购物车数据库的功能,现在需要在成功添加后,动态更新页面上的购物车列表区域。下面是具体的实现步骤:
第一步:重构控制器方法,返回更新后的购物车内容
我们需要让addStock方法在保存数据后,返回最新的购物车详情内容——推荐返回渲染好的HTML片段,这样前端可以直接替换页面内容,减少前端的拼接工作。
改进后的控制器代码:
public function addStock(Request $request) { // 保存数据到数据库 $data = new ShoppingCartDetail(); $data->cart_id = $request->input('cart_id'); $data->stock_id = $request->input('stock_id'); $data->price = 1; $data->save(); // 获取更新后的购物车所有商品数据(和你原来渲染$all_values_list的逻辑保持一致) $cartId = $request->input('cart_id'); $all_values_list = ShoppingCartDetail::where('cart_id', $cartId) ->with('stock') // 假设你有Stock模型关联,用来获取商品名称、图片等详情 ->get() ->map(function($item) { // 转换成和原页面$all_values_list一致的数组结构 return [ 'id' => $item->id, 'imageable_name' => $item->stock->imageable_name, 'stock_name' => $item->stock->name, 'without_tax' => $item->stock->without_tax, 'new_price' => $item->stock->new_price, 'tax_ratio' => $item->stock->tax_ratio, 'quantity' => $item->quantity, ]; }); // 返回渲染好的购物车列表HTML片段 return view('partials.shopping-cart-items', compact('all_values_list', 'cartId'))->render(); }
关键操作:把你原来页面中的
foreach循环代码,单独抽成一个局部视图文件resources/views/partials/shopping-cart-items.blade.php,原页面只保留一个空的容器来承载内容:<div id="shopping-cart-container"> @include('partials.shopping-cart-items') </div>
第二步:修改Ajax回调,替换页面内容
在Ajax请求成功后,直接用控制器返回的HTML片段替换购物车容器的内容:
改进后的Ajax代码:
$.ajax({ type: 'POST', url: '/sepetim', data: { '_token': $('input[name="_token"]').val(), 'cart_id': $('input[name=cart_id]').val(), 'stock_id': id }, success: function(response) { // 替换购物车区域的内容 $('#shopping-cart-container').html(response); // 可选:添加成功提示 alert("Başarılı bir şekilde eklendi."); }, error: function(xhr) { // 处理错误情况 alert("添加失败,请重试!"); } });
第三步:修复事件绑定失效问题(必做)
因为我们替换了HTML内容,原来通过onclick绑定的加减按钮、删除按钮事件会失效,需要用事件委托来重新绑定:
// 减号按钮事件委托 $(document).on('click', '.btn-number[data-type="minus"]', function() { var stockId = $(this).attr('id').replace('u', ''); buttons_click_minus(stockId); }); // 加号按钮事件委托 $(document).on('click', '.btn-number[data-type="plus"]', function() { var stockId = $(this).attr('id'); buttons_click_plus(stockId); }); // 输入框change事件委托 $(document).on('change', '.input-number', function() { input_onchange($(this).attr('id')); });
这样即使购物车内容被动态替换,按钮和输入框的事件依然能正常触发。
可选方案:返回JSON数据,前端手动渲染
如果你偏好前后端分离的模式,也可以让控制器返回JSON格式的购物车数据,前端用JavaScript拼接HTML:
控制器返回JSON:
public function addStock(Request $request) { // 保存数据... // 获取更新后的购物车数据并格式化 $cartId = $request->input('cart_id'); $all_values_list = ShoppingCartDetail::where('cart_id', $cartId) ->with('stock') ->get() ->map(function($item) { return [ 'id' => $item->id, 'imageable_name' => $item->stock->imageable_name, 'stock_name' => $item->stock->name, 'without_tax_formatted' => number_format($item->stock->without_tax, 2, ',', '.'), 'tax_amount' => number_format($item->stock->new_price - $item->stock->without_tax, 2, ',', '.'), 'tax_ratio' => $item->stock->tax_ratio, 'quantity' => $item->quantity, 'total_price' => number_format($item->quantity * $item->stock->new_price, 2, ',', '.'), ]; }); return response()->json([ 'success' => true, 'items' => $all_values_list ]); }
前端处理JSON并渲染:
$.ajax({ type: 'POST', url: '/sepetim', data: { '_token': $('input[name="_token"]').val(), 'cart_id': $('input[name=cart_id]').val(), 'stock_id': id }, dataType: 'json', success: function(response) { if (response.success) { const container = $('#shopping-cart-container'); container.empty(); // 循环生成每个商品的HTML $.each(response.items, function(index, item) { const itemHtml = ` <div class="sepeturunalan row d-flex align-items-center"> <div class="col-lg-1 col-sm-1 col-1"> <img src="http://vomsis.com/uploads/thumb_${item.imageable_name}" class="img-fluid"> </div> <div class="col-lg-4 col-sm-4 col-12 pl"> <a href="#" title="">${item.stock_name}</a> </div> <div class="col-lg-2 col-sm-2 col-2 text-center"> <span class="para">${item.without_tax_formatted}</span> </div> <div class="col-lg-1 col-sm-1 col-1 plr text-center"> <span class="para">${item.tax_amount} TL</span> <br/> <span class="fw">(${item.tax_ratio}%)</span> </div> <div class="col-lg-2 col-sm-2 col-2 text-center"> <div class="input-group adet"> <span class="input-group-btn"> <button type="button" id="${item.id}u" class="btn-number" data-type="minus"> <i class="fa fa-minus"></i> </button> </span> <input type="hidden" name="_token" value="${$('input[name="_token"]').val()}"> <input type="hidden" name="cart_id" value="${$('input[name=cart_id]').val()}"> <input type="hidden" name="stock_id" value="${item.id}"> <input type="text" id="${item.id}" name="name" class="input-number" value="${item.quantity}" min="1" max="25"> <span class="input-group-btn"> <button type="button" id="${item.id}" class="btn-number" data-type="plus"> <i class="fa fa-plus"></i> </button> </span> </div> </div> <div class="col-lg-2 col-sm-2 col-2 text-right"> <span class="para fw6">${item.total_price} TL</span> <br/> <span> <form action="/sepetim/${$('input[name=cart_id]').val()}/${item.id}" method="POST"> <input type="hidden" name="_token" value="${$('input[name="_token"]').val()}"> <input type="hidden" name="_method" value="DELETE"> <button type="submit" class="sepsil"> <i class="fa fa-trash-o"></i> 移除 </button> </form> </span> </div> <div class="col-lg-6 col-sm-6 col-6"> <p class="aciklama"> <i class="fa fa-info-circle renk"></i> <span class="para">满100TL免运费!此商品参与活动</span> </p> </div> </div> `; container.append(itemHtml); }); alert("Başarılı bir şekilde eklendi."); } }, error: function(xhr) { alert("添加失败,请重试!"); } });
这种方式适合需要更灵活控制前端渲染的场景,但需要维护前端的HTML模板代码。
内容的提问来源于stack exchange,提问作者ufuk
相关产品推荐
相关产品推荐

