【问题标题】:Ajax request works only the first time and no more after load part of the pageAjax 请求仅在第一次有效,在加载部分页面后不再有效
【发布时间】:2018-09-14 10:20:53
【问题描述】:

HTML 代码:

<div class="table-responsive">
    <table id="dataTable" class="table table-hover table-separated">
        <tbody>
            <tr id="test-1">
                <td class="test">
                    <form action="{{ url('/psy/update-test-status/'.$test->id) }}" method="POST" class="m-0">
                        <select name="status" class="form-control status_select">
                            <option class="text-success" value="active" selected>En ligne</option>
                            <option class="text-warning" value="inactive" >Inactif</option>
                            <option class="text-danger"  value="canceled" >Annulé</option>
                        </select>
                    </form>
                </td>
            </tr>
            <tr id="test-2">
                <td class="test">
                    <form action="{{ url('/psy/update-test-status/'.$test->id) }}" method="POST" class="m-0">
                        <select name="status" class="form-control status_select">
                            <option class="text-success" value="active" selected>En ligne</option>
                            <option class="text-warning" value="inactive" >Inactif</option>
                            <option class="text-danger"  value="canceled" >Annulé</option>
                        </select>
                    </form>
                </td>
            </tr>
            <tr id="test-3">
                <td class="test">
                    <form action="{{ url('/psy/update-test-status/'.$test->id) }}" method="POST" class="m-0">
                        <select name="status" class="form-control status_select">
                            <option class="text-success" value="active" selected>En ligne</option>
                            <option class="text-warning" value="inactive" >Inactif</option>
                            <option class="text-danger"  value="canceled" >Annulé</option>
                        </select>
                    </form>
                </td>
            </tr>
        </tbody>
    </table>
</div>

JavaScript 代码:

$(document).ready(function () {

        // change color of selected element according to its value
        function statusSelect(element) {
            if ($(element).val() == 'active') {
                $(element).removeClass('text-warning');
                $(element).removeClass('text-danger');
                $(element).addClass('text-success');
            }
            else if ($(element).val() == 'inactive') {
                $(element).removeClass('text-success');
                $(element).removeClass('text-danger');
                $(element).addClass('text-warning');
            }
            else if ($(element).val() == 'canceled') {
                $(element).removeClass('text-success');
                $(element).removeClass('text-warning');
                $(element).addClass('text-danger');
            }
        }

        // Post form data and load the table again
        function updateTestStatus(element) {
            form = $(element).parent('form');
            tr = form.closest('tr');
            dest_url = form.attr('action');
            $.ajax({
                type:"POST",
                url:dest_url,
                data:form.serialize(),
                dataType: 'json',
                headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
                success: function(data){
                    if($.isEmptyObject(data.errors)){
                        $('#dataTable').load(document.URL +  ' #dataTable');
                        statusSelect($(element));
                    }
                    else {
                        // code...
                    }
                },
                errors: function (data) {
                    // code...
                }
            });
        }

        $('select.status_select').each(function (elem) {
            statusSelect($(this));
        });

        $('select.status_select').on('change', function (e) {
            statusSelect($(this));
            updateTestStatus($(this));
        });
});

其实我至少有四个问题:

  • 我不确定如何订购和/或覆盖函数eachon change
  • 我不能在 ajax 成功回调中只加载 tr 元素:加载完整的 table 时它工作正常,但是当我加载 $('#dataTable tr#test-1').load(document.URL + ' #dataTable tr#test-1'); 时,它会在前一个 tr 中加载 tr 而不是替换它。
  • statusSelect 方法(更改所选输入文本的颜色)第一次有效,但在 Ajax 加载后不再有效
  • updateTestStatus 方法(Ajax 调用然后重新加载页面的一部分)第一次有效,但之后不再有效。

编辑:第三和第四个问题现已解决(成功回调中的函数在加载函数完成之前执行)

更新代码:

function statusSelect(element) {
            if ($(element).val() == 'active') {
                $(element).removeClass('text-warning');
                $(element).removeClass('text-danger');
                $(element).addClass('text-success');
            }
            else if ($(element).val() == 'inactive') {
                $(element).removeClass('text-success');
                $(element).removeClass('text-danger');
                $(element).addClass('text-warning');
            }
            else if ($(element).val() == 'canceled') {
                $(element).removeClass('text-success');
                $(element).removeClass('text-warning');
                $(element).addClass('text-danger');
            }
        }

        function updateTestStatus(element) {

            form = $(element).parent('form');
            tr = form.closest('tr');
            dest_url = form.attr('action');
            $.ajax({
                type:"POST",
                url:dest_url,
                data:form.serialize(),
                dataType: 'json',
                headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
                success: function(data){
                    if($.isEmptyObject(data.errors)){
                        var row_id = tr.attr('id');
                        $('#dataTable #'+row_id).load(document.URL +  ' #dataTable #'+row_id, function() {
                            testStatus();
                        });
                    }
                    else {
                        // code...
                    }
                },
                errors: function (data) {
                    // code...
                }
            });
        }

        function testStatus () {
            $('select.status_select').each(function (elem) {
                statusSelect($(this));
            });

            $('select.status_select').on('change', function (e) {
                statusSelect($(this));
                updateTestStatus($(this));
            });
        }

        testStatus();
    });

我还有一个问题:我希望能够仅加载 &lt;tr&gt; 而不是所有 &lt;table&gt;...

$('#dataTable tr#test-1').load(document.URL + ' #dataTable tr#test-1'); 给我:

<table><tr id="test-1"><tr id="test-1">...</tr></tr></table>

编辑 2:已解决!

看起来加载方法“附加在内部”,而不是像我认为的那样“替换”。这条线成功了:

$('#dataTable #'+row_id).load(document.URL +  ' #dataTable #'+row_id, function() {
    $(this).children(':first').unwrap(); // This one
    testStatus();
});

这个帖子帮助了我:How can I use jQuery.load to replace a div including the div


最终编辑

ajax 函数有时会因为 each 被调用多次。 以下是我的解决方法:

success: function(data){
    if($.isEmptyObject(data.errors)){
        var row_id = tr.attr('id');
        $('#dataTable #'+row_id).load(document.URL +  ' #dataTable #'+row_id, function() {
            $(this).children(':first').unwrap();

            $('#'+row_id+' select.status_select').on('change', function (e) {
                statusSelect($(this));
                updateTestStatus($(this));
            });
            $('select.status_select').each(function (elem) {
                statusSelect($(this));
            });
        });
    }
}

【问题讨论】:

    标签: javascript jquery ajax


    【解决方案1】:

    Ajax 动态加载 HTML。 JavaScript 无法按预期使用动态 HTML。

    您可以将 JavaScript 包装在一个函数中,并在加载/就绪时调用它一次,然后在 success 上再次调用它。

    $(document).ready(function () {
       function ajaxFunction (args) {
            $.ajax({
                type:"POST",
                url: url,
                data: data,
                dataType: 'json',
                headers: {header object},
                success: function(data){
    
                afterAjax (); // call the functions you want to perform again
                    // code...
                },
                errors: function (data) {
                    // code...
                }
            });
        }
        function afterAjax () {
            // functions to perform again after dynamic HTML load
        }
        afterAjax ()
    });
    

    【讨论】:

    • 我想我做到了:我已经在成功调用 statusSelect 函数。或者我误解了你写的内容......
    • 您必须再次添加您的事件监听器(包括任何.on() 方法),因为它们已绑定到不再存在的元素(更新 DOM 元素实际上会删除它们并放置新的),所以您需要为新创建的 DOM 元素添加事件监听器。
    • 我明白了,但我找不到实现它的方法...即使我将 .each() 和 .on('change') 放入成功回调中,也没有任何反应...你能用我的代码提供一个具体的例子吗?
    • 我认为成功回调中的函数在加载方法完成之前执行。
    • 是的,这是第一个问题。通过向加载方法添加回调来解决它:$('#dataTable').load(document.URL + ' #dataTable', function() { myFunction(); });
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多