首页 > 解决方案 > AJAX 调用后,我的 JS 代码在我刷新页面之前不会加载

问题描述

所以我在 Laravel 有一个项目,我添加了过滤器,它可以很好地过滤产品。但是,当产品被过滤时,我的添加到购物车按钮变得无响应。我在浏览器中检查了呈现的代码后发现 JS 没有加载。但是,如果我手动刷新页面(或使用 刷新代码location.reload()),那么它可以工作。但是我想避免手动刷新,因为那样我会丢失添加到按钮以显示其活动过滤器的颜色类。

下面是我的产品文件的代码,它从控制器的 for 循环中加载产品:

products.blade.php

<div class="container">

    <!--Grid row-->
    <div class="row">
    @foreach ($products as $p)
            <div class="col-lg-3">
                <div class="container">
                    <form action="{{ route('cart.add', $p->id) }}" data-id="{{ $p->id }}" id="addtocart">
                        <div class="row">
                            <h5>{{ $p -> name }}</h5>
                            <button type="button" id="submit" class="button has-shadow is-danger submit is-small">
                                    Add to Cart
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        @endforeach
    </div>

    <div class="container">
        {{ $products ->appends($request->query()) -> links() }}
    </div>

</div>
                  

products_show.blade.php - JS 所在的位置以及上述文件的加载位置。$('body').on('click', '.btn-filter'调用后会出现此问题。

@extends ('layouts.app')

@section ('content')

    <div class="box text-right">
        <div class="row">
            <button type="button" name="filter[]" value="Jackets" id="filterJackets" class="button is-info btn-filter">Jackets</button>
            <button type="button" name="filter[]" value="Hoodies" id="filterHoodies" class="button is-info btn-filter">Hoodies</button>
        </div>
    </div>

    <section class="products">
        @include('product.products')
    </section>

@endsection


    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type="text/javascript">

        $(document).ready(function () {

            $(document)
                .ajaxStart(function () {
                    $("#modal").show();
                })
                .ajaxStop(function () {
                    $("#modal").hide();
                });
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });


            // Pagination
            $('body').on('click', '.pagination a', function(e) {

                var url = $(this).attr('href');

                $.ajax({
                    url : url
                }).done(function (data) {
                    $('.products').html(data);
                }).fail(function () {
                    alert('Products could not be loaded.');
                });

                window.history.pushState("", "", url);
            });



            // Add to cart
            $(".submit").click(function (e) {
                e.preventDefault();
                var p_id = $(this).closest("form").data('id');
                var product_id = $("#product_id").val();
                
                var url = $(this).closest('form').attr('action');

                $.ajax({
                    url:url,
                    method:'POST',
                    data:{
                        product_id:product_id
                    },
                    success:function(response){
                        console.log("added to cart success");
                    },
                });
            });



            $('body').off('click', '.btn-filter', function(e) {
                $(this).removeClass("is-success");
            });

            $(".btn-filter").hover(function(){
                $(this).addClass("is-danger");
            }, function(){
                    $(this).removeClass("is-danger");
            });



            var filters = [];

            $('body').on('click', '.btn-filter', function(e) {
                e.preventDefault();
                $(this).toggleClass('is-success');

                filters = []; // reset
                
                $('button[name="filter[]"]').each(function()
                {
                    if ($(this).hasClass("is-success")) {
                        filters.push($(this).val());
                    }
                });

                var url = '{{ route('products.type') }}'+'?filter[storage]='+filters

                $.ajax({
                    url : url
                }).done(function (data) {
                    $('.products').html(data);
                }).fail(function () {
                    alert('Products could not be loaded.');
                });

                window.history.pushState("", "", url);

            });

        });
    </script>

我不确定 php 代码是否重要,因为这里的问题是添加到购物车按钮 JS 没有被调用,但无论如何都是这样:

public function filterByType(Request $request){
        $products = QueryBuilder::for(Auth::user()->products())
            ->allowedFilters(['type'])->paginate()
            ->appends(request()->query());

        // Check if request is from ajax
        if ($request->ajax()) {
            return view('product.products', ['products' => $products])->render();
        }

        return view('product.products_show', compact('products'));

    }

谢谢。

标签: javascriptjqueryajaxlaravel

解决方案


所以我找到了一个hackway来做到这一点,但是有更好的解决方案或解决我的问题的方法吗?我在这里做错了吗?:

我添加location.reload()btn-filter单击的末尾,这将重新加载页面,因为重新加载页面为我解决了这个问题。

然后我将下面的代码添加到脚本的顶部:

var window_url = window.location.href;
var url_filter_params = window_url.substr(window_url.indexOf("=") + 1)
var filter_params_array = url_filter_params.split(',');

$('button[name="filter[]"]').each(function()
{
    if ($.inArray($(this).val(), filter_params_array) >= 0){
        $(this).addClass('is-success');
    }
});

这基本上是获取 URL 解析它以获取参数,然后显示将 is-warning 类添加回按钮以使其显示为选中状态。过滤器也可以工作。


推荐阅读