Дождитесь подтверждения, прежде чем начинать цикл ForEach - PullRequest
0 голосов
/ 17 июня 2019

У меня есть вызов API, который ответит на список, и я хочу показать диалоговое окно для каждой ошибки, но я хочу, чтобы следующее диалоговое окно (а) отображалось после того, как я нажал Да для первой. Как мне справиться с этим? потому что на данный момент, он продолжает цикл, даже если нет выбранного ответа.

Я попробовал ответ из этой ссылки , но у меня это не сработало.

Есть ли другой способ справиться с этим?

 timeSheetApi
    .validate(clonedTimesheet)
    .then(function (resp) {
     var validationErrors = resp.data;

     line.ErrorCount = 0;
     line.WarningCount = 0;
     line.Errors = "";

     if (validationErrors.length > 0) {
         line.ErrorCount = validationErrors.length;

         validationErrors.forEach(detail,index){
            let confirm = $mdDialog.confirm()
                          .title('')
                          .htmlContent(detail.Message)
                          .ok('Yes')
                          .cancel('No');

        $mdDialog.show(confirm).then(function(){
            //yes
            //i want the loop to wait for this yes
        }, function(){
            //no
            // and exit this loop if no was selected
        });
         }

         line.Errors = cleanErrorMessage(line.Errors);
         triggerOption(sourceColumn, prop, index, val, time_field);

         return line;
                }).catch(function (err) {
                exceptionService.resolve(err);
            });

Ответы [ 3 ]

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

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

Что вы можете сделать, так это то, что вы можете создавать и показывать каждое диалоговое окно только после закрытия предыдущего диалога.Обратите внимание на модифицированную версию вашего скрипта, где вместо циклического повторения ошибок валидации (с forEach) я продолжаю обрабатывать ошибку, показывая ее диалоговое окно, и после закрытия указанного диалога я продолжаю обрабатывать следующую ошибку, повторно используятот же массив validationErrors:

timeSheetApi
    .validate(clonedTimesheet)
    .then(function (resp) {
        var validationErrors = resp.data;

        line.ErrorCount = 0;
        line.WarningCount = 0;
        line.Errors = "";

        function process_next_error() {
            const next_error = validationErrors.shift();
            if(!next_error) return; /// No more validation errors
            let confirm = $mdDialog.confirm()
              .title('')
              .htmlContent(timesheetError.Message)
              .ok('Yes')
              .cancel('No');
            $mdDialog.show(confirm).then(process_next_error);
        }

        process_next_error();

        line.Errors = cleanErrorMessage(line.Errors);
        triggerOption(sourceColumn, prop, index, val, time_field);

        return line;
    }).catch(function (err) {
        exceptionService.resolve(err);
    });

Вышеуказанная функция «обработчик» - это функция process_next_error - она ​​вызывается непосредственно сценарием для обработки первой ошибки, но также и сценарийиспользует в качестве обратного вызова для обещания show(confirm), которое разрешается при закрытии диалога.

Когда больше не осталось ошибок, process_next_error просто возвращается, ничего не делая.

The validationErrors массив будет пуст к тому времени, когда закроется последнее диалоговое окно, потому что я постепенно «сдвигаю» элементы из него.Я предполагаю, что это не проблема, потому что что-то говорит мне, что validationErrors является очень временной переменной в вашем приложении.Если вы хотите сохранить элементы изначально в массиве validationErrors, вы либо берете его копию, либо выполняете итерацию по нему вместо использования shift.

0 голосов
/ 18 июня 2019

Я думаю, вы должны перекодировать его без использования forEach. Вот демоверсия , в которой вы можете перебирать каждый элемент, не используя forEach.

0 голосов
/ 17 июня 2019

Вы должны использовать await там и использовать простой цикл for. Цикл foreach принимает обратный вызов, и вы получили обещание, поэтому его там нет.

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