繁体   English   中英

如何从 laravel controller function 返回视图?

[英]How to return a view from laravel controller function upon ajax call?

我正在做一个书店项目,可以将书籍添加到购物车,用户可以 select 许多书籍将它们添加到购物车。 当用户单击“ Add to Cart ”按钮时,我将所选书籍的 ID 添加到名为cart的 JS 数组中。 When all the selected books are added to the cart then I want to link <a> tag with ajax call that will hit the url of a controller function and will send the JS cart array object to the controller function and then in the controller function,我想将视图返回给浏览器,我不希望 controller function 将响应返回给 ajax 调用,而是将视图返回给浏览器。

这是 JS function 将所选书籍的 ID 添加到cart JS 数组中:

function addToCart(id)
{
if(! cart.includes(id) ) cart.push(id);

cartLength.html(cart.length);
$('#successCart'+id).html('Book added to cart.');

}  

这是调用 ajax function 的<a>标记,function 名称是 showCart():

<a href="#" onclick="event.preventDefault(); showCart();">
  <i class="fa fa-shopping-cart"></i>
  <span id="cartLength"></span>
</a>  

这是具有 ajax 代码的showCart() function :

function showCart()
{


$.ajaxSetup({
      headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
      }
    });

$.ajax({
        url:"cart",
        method:'post',
        data:{cart:cart},
        dataType: 'html'
  })
 .done(function(msg){


  });
 .fail(function(msg){
    alert(msg.responseJSON.errors);
 });
}  

Here is the controller function - I want this function to directly return the view to the browser without sending it back to the ajax call:

public function showCart(Request $request)
{
    return view('cart', ['cart' => $request->cart ]); // this should be returned to the browser and not to the ajax call
}  

这是 controller function 的路线:

Route::post('/cart', 'HomeController@showCart')->name('home.cart');  

编辑:

我已经用以下技巧暂时解决了这个问题,但这不是一个永久的解决方案:

After calling the showCart() function from ajax for sending the cart array variable from js to laravel controller, I used the following logic to store the books in a session variable whose ids are stored in the cart array:

public function showCart(Request $request)
{

    session()->put('cart_books', Book::whereIn('id', $request->cart)->get()); 
    session()->save();
    return "success";

}  

将查询结果存储在 session 变量中后,我为/cart创建了另一个GET路由,如下所示:

Route::get('/cart', 'HomeController@viewCart');  

然后在 ajax 调用成功post ,我使用get方法调用/cart ,如下所示:

.done(function(msg){
    console.log('calling cart');
    location.href = "cart"; // Here I call the `/cart` with `get` method which will hit the `viewCart()` function of HomeController which will return the view back to the browser along with the results that were stored in the session variable.

  })  

这是viewCart() controller function 将视图返回到浏览器并将 session 变量的数据发送到视图:

public function viewCart()
{
   $random_books = Book::all()->random(4);
   $categories = Category::all();
    return view('cart', ['cart_books' => session()->get('cart_books'), 
  'random_books' => $random_books, 'categories' => $categories]); 
}

我希望 controller function 将视图返回到浏览器而不将其返回到 ajax 调用,任何帮助都提前表示感谢。

您可以通过渲染并返回 controller 中的视图,从 ajax 调用返回 Raw html,

return view('cart', ['cart' => $request->cart])->render();

这将返回原始 HTML,您可以进一步使用它。 However, returning HTML from ajax is not a good way, You can return JSON from the controller and render the view in frontend according to the JSON data.

在 controller function 中只需添加渲染方法,如下行

public function showCart(Request $request)
{
   return view('cart', ['cart' => $request->cart ])->render();
}  

对于 js:

$.ajax({
method: 'POST', // Type of response and matches what we said in the route
url: '{{ route('home.cart') }}', // This is the url we gave in the route
data: {'cart' : cart}, // <-- this is your POST data
success: function(response){ // What to do if we succeed
    console.log(response);
},
error: function(jqXHR, textStatus, errorThrown) { // What to do if we fail
    console.log(JSON.stringify(jqXHR));
    console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
});

你正在做一个 XHR,所以你不应该从你的 controller 返回整个 HTML视图,除非你打算用返回的addToCart替换现有元素,就像你正在做的那样。 您在这里需要的是 POST 之后的重定向,而您的临时解决方案实际上并不是一个糟糕的解决方案:) 这是一个与您的问题相似的问题,答案相同。 事实上,我强烈推荐您的临时解决方案,而不是下面的替代解决方案。


由于您希望使用从 controller 返回的视图而不将其返回到 ajax,因此一种相当非正统的方法是通过<form>进行 POST。 您可以使用数据的<input>动态创建<form>并提交。

function postData(actionUrl, method, data) {
    var mapForm = $('<form id="mapform" action="' + actionUrl + '" method="' + method.toLowerCase() + '"></form>');
    for (var key in data) {
        if (data.hasOwnProperty(key)) {
            mapForm.append('<input type="hidden" name="' + key + '" id="' + key + '" value="' + data[key] + '" />');
        }
    }
    $('body').append(mapForm);
    mapForm.submit();
}

function showCart()
{
    postData('cart', 'post', cart);
}

我从这里借用了上面的代码。 你也可以对vanilla JS 做同样的事情。

正如其他人所说,您可以使用

return view('cart', ['cart' => $request->cart])->render();

在你 jQuery 做

.done(function(response){
    document.write(response);
});

或者您可以返回其内容应显示给用户的链接,并在您的 done 方法中重定向用户。 所以在你的后端你会有

return route('cart', ['cart' => $request->cart]);

在您的前端,您将拥有

.done(function(response){
    location.href = response;
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM