AJAX-запрос не всегда последовательно обновляет информацию - PullRequest
0 голосов
/ 04 июня 2019

Я испытываю некоторые проблемы с обновлением страницы 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 как кеш-нет, а также не отправлял заголовки кеша. Я бегу в вампе.

1 Ответ

1 голос
/ 04 июня 2019

В вашем случае ваш код обновления будет всегда запускаться до обновления ваших данных.Поскольку 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, но я не рекомендую это делать, поскольку вы не уверены, когда обновление будет выполнено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...