Шаги мастера jQuery перемещаются до завершения вызова ajax

Как я могу контролировать переход к следующему шагу в соответствии с результатом вызова ajax? data.d возвращается с логическим значением

$("#wizard").steps({
            onStepChanging: function (event, currentIndex, newIndex) {
                var move = false;
                if (currentIndex == 2) {
                    move = false;
                    $.ajax({
                        type: 'POST',
                        url: "Reservation.aspx/SomeFunction",
                        data: serializeData({  }),
                        contentType: "application/json",
                        dataType: 'json',
                        success: function (data) {
                            move = data.d;
                            return true;
                        },
                        error: ajaxLoadError
                    });
                }
                return move;
            },
            saveState: true

        });

person heeema    schedule 25.11.2013    source источник
comment
Я не использовал шаги мастера jquery, но ваша проблема возникает из-за асинхронного вызова ajax. Проверьте другой плагин мастера, который принимает загрузку ajax (например: github.com/mstratman/jQuery-Smart- Мастер)   -  person Gasim    schedule 26.11.2013


Ответы (8)


У меня та же проблема, я даже думал использовать «setStep», чтобы принудительно выполнить шаги после загрузки ajax, тогда последняя версия jquery.steps удалила «setStep»..

В итоге я использую метод «следующий» и должен использовать глобальный триггер, чтобы остановить бесконечный цикл для события onChanging, короче говоря, я заставляю мастера перейти к следующему шагу, если ajax возвращает действительные данные, в противном случае он остается текущий шаг, вот код

var $stopChanging = false; 

.... ....

onStepChanging: function (event, currentIndex, newIndex) {
      if ($stopChanging) {
        return true;
      } else {
        items = $.ajax({
        type: 'POST',
        url: "Reservation.aspx/SomeFunction",
        data: serializeData({  }),
        contentType: "application/json",
        dataType: 'json',
        success: function (data) {
            $stopChanging = true;
            wizard.steps("next");
        },
        error: ajaxLoadError
    });
   },
   onContentLoaded: function (event, currentIndex) {
       $stopChanging = false;
   }
}

Логика такая:

  1. Нажмите кнопку «Далее», чтобы вызвать onStepChanging
  2. По умолчанию установите событие jquery.steps onStepChanging, возвращающее false, затем вызовы $.ajax, если они возвращают действительные данные (успех), вызовите jquery.steps, чтобы перейти к следующему шагу, и снова сработает onStepChanging, если он недействителен , ничего не делать, остаться на текущем шаге

запускать два события onStepChanging каждый раз не звучит хорошей идеей, но это то, что я могу сделать на данный момент

Возможно, вам потребуется добавить дополнительные условия для различных поведений шагового индекса.

person Joe Lu    schedule 15.01.2017
comment
Это не похоже на полный ответ. - person RBT; 16.01.2017
comment
Гайз, это настоящий ответ, который больше ничего не работает. Мне потребовалось 2 дня, чтобы понять этот ответ, спасибо, чувак, много времени тратится впустую на бесконечный цикл каждый раз, когда создается ..... - person MR_AMDEV; 20.05.2019

вы можете использовать подход Сэми с синхронным запросом ajax

$("#wizard").steps({
    onStepChanging: function (event, currentIndex, newIndex) {
        if (currentIndex == 2) {
            var requestResult = $.ajax({
                type: 'POST',
                url: "Reservation.aspx/SomeFunction",
                async: false,
                contentType: "application/json",
                dataType: 'json',
                error: ajaxLoadError
            });
            return requestResult.responseJSON.Result == "/*your expected value*/"
        }
    },
    saveState: true
});
person AntonE    schedule 24.06.2015

Если вы не хотите, чтобы функция $.ajax() возвращалась немедленно, установите для параметра async значение false:

Установите тайм-аут для Ajax, если сервер не отвечает на ваш вызов ajax, тогда он перейдет к следующему процессу.

$("#wizard").steps({
            onStepChanging: function (event, currentIndex, newIndex) {
                var move = false;
                if (currentIndex == 2) {
                    move = false;
                    $.ajax({
                        type: 'POST',
                        url: "Reservation.aspx/SomeFunction",
                        data: serializeData({  }),
                        contentType: "application/json",
                        dataType: 'json',
                        async: false,
                        cache: false,
                        timeout: 30000,
                        success: function (data) {
                            move = data.d;
                            return true;
                        },
                        error: ajaxLoadError
                    });
                }
                return move;
            },
            saveState: true

        });
person Nirav Patel    schedule 11.03.2016
comment
Как я уже сказал, я хотел бы знать, существует ли какой-либо асинхронный подход. - person Manolo; 11.03.2016
comment
Да, я это читал, но забыл упомянуть, что без ASYNC с этим очень сложно справиться. Это возможно с помощью setTimeout(function () {Ваш код AJAX}, 1000); но это не безопасный способ обработки. Приведенное выше решение является безопасным и безопасным, если у вас нет проблем с ASYNC. - person Nirav Patel; 11.03.2016
comment
Вы получили помощь от ответа выше? - person Nirav Patel; 13.03.2016
comment
Нет, это мой фактический подход. Я ищу асинхронный подход. Однако я не уверен, что это возможно с этим плагином. Если нет, я продолжу устанавливать async на false. В любом случае, награда за асинхронный подход. - person Manolo; 13.03.2016
comment
Посмотрите на ответ @Сами. Он отвечает в основном так же, как и вы. - person Manolo; 13.03.2016
comment
В порядке. Спасибо за вашу помощь, но совсем не помогает, потому что на это уже был дан ответ. - person Manolo; 13.03.2016
comment
Асинхронные вызовы завершаются всякий раз, когда они чертовски хороши. Вы не можете контролировать завершение асинхронного вызова. Вы пытаетесь заставить асинхронный вызов вести себя как обычный вызов, а это невозможно. Возможно, вам стоит пересмотреть свой подход. Установка async в false или добавление тайм-аута даст вам то, что вы хотите. - person Ayush Sharma; 16.03.2016

Я нашел другой способ, как решить эту проблему. OnStepChanging поддерживает только boolean. Существует запрос на вытягивание #232, который добавляет использование отложенного объекта. (Я также нашел способ использовать отложенный объект на GitHub. ) Я включил эту модифицированную версию в свой проект и использовал ее в OnStepChanging вот так:

    var def = $.Deferred();

    $.ajax({
        type: "POST",
        url: url,
        //async: false,
        beforeSend: function (xhr) {
            //ASP CORE Antiforgery token
            xhr.setRequestHeader("RequestVerificationToken",
                $('input:hidden[name="__RequestVerificationToken"]').val());
        },
        data: data,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        failure: function (xhr) {
            failureCallback(xhr);
        }
    }).done(function (response) {
        //Result of server validation
        var responseResult = response.result === "Success" ? true : false;
        // Check response
        def.resolve(responseResult);
        }).fail(function (response) {
            console.log(response);
            return false;
        });

    return def; // This is the Deferred that should be returned and NOT the one from jQuery Ajax

Я надеюсь, что это поможет кому-то еще. :-)

person Josef Trejbal    schedule 13.02.2019

$("#wizard").steps({
        onStepChanging: function (event, currentIndex, newIndex) {
            var $out= false;
            if (currentIndex == 2) {
                $out= false;
                $.ajax({
                    type: 'POST',
                    url: "Reservation.aspx/SomeFunction",
                    data: serializeData({  }),
                    contentType: "application/json",
                    dataType: 'json',
                    success: function (data) {
                        move = data.d;

                        $out = true;
                    },
                    error: ajaxLoadError
                });
            }
            return $out;
        },
        saveState: true

    });

Поместите глобальную переменную $out!

person luisbg    schedule 15.10.2014

Я столкнулся с похожей проблемой, но использовал для проверки parsleyjs. Вы можете получить представление о моем коде.

Мой код такой:

             onStepChanging: function (event, currentIndex, newIndex) {

                 // ======== Code that fails 

                 //var step = $wizard_advanced.find('.body.current').attr('data-step'),
                 //$current_step = $('.body[data-step=\"'+ step +'\"]');                        


                // check input fields for errors
                //$current_step.find('[data-parsley-id]').each(function() {
                    //this adds .md-input-danger to inputs if invalid
                    //there is remote validation occurring here via ajax
                    // async: false
                    //$(this).parsley().validate();
                //});

                // this is executed before ajax validation is finished 
                //return $current_step.find('.md-input-danger').length ? false : true;

                // ======== END of Code that fails 

                // FIX
                // waits on ajax validation to finish before returning
                if( $wizard_advanced_form.parsley().validate() ) {
                    return true;
                } else {
                    return false;
                }
                //FIX                    
            }
person ambay    schedule 20.01.2016

Вот единственный способ, которым я смог приступить к работе после нескольких попыток, - это то, что @joe-lu получил выше. Вы просто хотите запустить асинхронный вызов и вернуть false. Это позволит мастеру оставаться на том же шаге. ТОГДА в обработчике успеха вы программно переходите к следующему шагу.

$("#wizard").steps({
            onStepChanging: function (event, currentIndex, newIndex) {
                if (currentIndex == 2) {
                    //Would be a good idea to start a spinner here!
                    //would be a good idea to disable next button here!
                    $.ajax({
                        type: 'POST',
                        url: "Reservation.aspx/SomeFunction",
                        data: serializeData({  }),
                        contentType: "application/json",
                        dataType: 'json',
                        success: function (data) {
                            //stop spinner here!
                            //programmatically move to next step on success.
                            $("#wizard").steps("next");
                        },
                        error: ajaxLoadError
                    });
                }
                //Prevents natural movement to next step.
                //will be done programmatically
                return false;
            },
            saveState: true
        });
person Scott Jones    schedule 24.01.2018

person    schedule
comment
Кажется, нет способа заставить его работать асинхронно, поэтому я награжу вас наградой, потому что это единственный способ заставить его работать. - person Manolo; 16.03.2016