首页 > 解决方案 > AJAX 查询并不总是一致地更新信息

问题描述

我在 AJAX 更新页面时遇到了一些问题。数据库中的实际数据会更新,但这并不总是实时反映在网页上。

例如,我有以下事件:

    $("#add_note").click(function(e) { 
        //e.preventDefault();       
        $("#add_note_form").validate({ 
            rules: {
              contact_note: {
                required: true
              }
            },
            submitHandler: function(form) {
                contact.modal_update({
                    'obj' : $('#add_note_form'),
                    'uri' : '/contact/add_note/'
                });
            }
        }); 
    });

此函数在创建新便笺时调用回调以首先验证表单字段,然后如果成功则在单独的类中调用回调以进行更新。请参阅下面的 modal_update 类:

// Update modal
this.modal_update = function(data) 
{//
    // Declare a few variables for the data object we've received
    obj = data.obj // The form element to serialize
    uri = data.uri;
    // Get the form ID from the data-target attribute 
    id = obj.attr('data-target');
    // URL to send to 
    url = this.site_url + uri + id;     
    // The form object
    this.post_data(obj.serialize(),url);
    // Hide Modal
    obj.closest('.modal').modal('hide');    
    // Refresh 
    this.refresh();
}

然后找出正确的 ajax 路由并在同一个类中调用 ajax 回调:

// AJAX post
this.post_data = function(obj,uri)
{
    $.ajax({
        data: obj,
        dataType: 'json',
        type: 'post',
        url: uri,
        headers: { "cache-control": "no-cache" },
        cache: false,
        success: function (response) {
           if (response.success == true)
           {

                $("#alert_success .msg").html(response.message);
                $("#alert_success").fadeIn(200).delay(2000).fadeOut(200);
           }
            else 
           {
                $("#alert_error .msg").html(response.error);
                $("#alert_error").fadeIn(200).delay(2000).fadeOut(200);
                console.log(response.error);
           }
        }
    });     
}

然后我运行另一个类回调来“刷新”页面上所有元素中的数据:

this.refresh = function() 
{
    // Refresh the ajax requests
    this.get_contact_data();
    this.get_notes();
    this.get_contact_log();
    this.get_contact_tasks();   
}

此类重新加载在页面加载时运行的函数,以将初始数据获取到页面上的表/字段中。请参阅下面的“get_notes”:

// Get notes
this.get_notes = function() 
{
    // Get all notes and populate table
    var log_uri = this.site_url + "/contact/get_notes/" + this.contact_id; 

    this.get_data(log_uri,function(data) {
        notes = $("#contact_notes ul");
        notes.empty("");
        // Populate the contact fields, assuming there is a result to play with
        if (data != false)  {
            //alert(JSON.stringify(data));
            $("#notes-tab .count").html("(" + data.length + ")");
            $.each( data, function( key, value ) {
                notes.append("<li class='list-group-item' modal-id='editNoteModal' data-target='" + value.ID + "'><div class='row'><div class='col-lg-3'><i class='fa fa-sticky-note mr-3'></i>" + value.timestamp + "</div><div class='col-lg-7'>" + value.note + "</div><div class='col-lg-2'><a href='#' class='edit mr-3'><i class='fa fa-edit mr-1'></i>Edit</a><a href='#' class='delete'><i class='fa fa-times mr-1'></i>Remove</a></div></div></li>");
            });
            console.log('Notes loaded');
        } else {
            notes.append("<li>There are currently no notes for this contact</li>");
        }
    });
}

现在的问题:

由于某种原因,这不会实时一致地更新。数据在服务器端更新得很好,但在客户端更新/刷新并不总是更新。我可能会添加一个注释并获得正确的更新响应,但刷新方法似乎正在接收旧数据并且总是落后一个注释。所以下次我添加注释时,我之前添加的注释就会出现,依此类推。

我遇到的另一个问题是方法似乎堆叠在每个事件上,所以如果我添加一个注释(或其他方法之一),我会看到控制台说“加载了注释”,但在第二个注释上它说“加载了注释”两次,然后在第 3 个音符上添加 3 次,以此类推。

我确信我的代码设计中一定存在致命缺陷,但我对 javascript/jquery 的经验不足,无法注意到我出错的方向,因此我可以修复它。

我认为这是 ajax 缓存的问题,没有刷新结果,所以我将 ajax 请求调整为无缓存,并且不发送缓存标头。我在沼泽中奔跑。

标签: javascriptjqueryajax

解决方案


在您的情况下,您的刷新代码将始终在您的数据更新之前运行。因为 ajax 是异步的,所以 ajax 后面和下面的代码将总是几乎在你的 ajax 运行时执行。

在您运行post_data函数以调用 API 时,该refresh函数也开始运行。所以它是在你的数据更新之前完成的。

您应该在 ajax 回调中运行刷新函数。例如:

this.post_data = function(obj,uri, callback)
{
    $.ajax({
        data: obj,
        dataType: 'json',
        type: 'post',
        url: uri,
        headers: { "cache-control": "no-cache" },
        cache: false,
        success: function (response) {
           if (response.success == true)
           {

                $("#alert_success .msg").html(response.message);
                $("#alert_success").fadeIn(200).delay(2000).fadeOut(200);
           }
            else 
           {
                $("#alert_error .msg").html(response.error);
                $("#alert_error").fadeIn(200).delay(2000).fadeOut(200);
                console.log(response.error);
           }
           callback();
        }
    });     
}

在 中modal_update,您将刷新函数作为回调传递给 post_data:

this.modal_update = function(data) 
{//
    // Declare a few variables for the data object we've received
    obj = data.obj // The form element to serialize
    uri = data.uri;
    // Get the form ID from the data-target attribute 
    id = obj.attr('data-target');
    // URL to send to 
    url = this.site_url + uri + id;     
    // The form object
    this.post_data(obj.serialize(),url, this.refresh);
    // Hide Modal
    obj.closest('.modal').modal('hide');    
}

您应该阅读有关异步 ajax 的更多信息。您可以使用其他棘手的解决方案 setTimeout 来运行this.refresh,但我不建议您这样做,因为您不确定更新何时完成。


推荐阅读