2015-08-17 2 views
4

У меня есть следующий кодБорясь с асинхронным характером AngularJs JavaScript

if (testNavigation() && $scope.selections.somethingChanged) { 
    return false; 
} 

в testNavigation Я звоню модальное диалоговое окно и если я отвечу Ok в этом диалоге, я вновь установить somethingChanged ложь. Моя проблема в том, что когда код выполняется, диалог testNavigation и модальный обход и выполняется позже, и поэтому мой тест не работает, так как мне нужно, чтобы он работал. Что я должен изменить, чтобы моя логика правильно работала, например. сначала вызовите мой модальный диалог и действуйте соответственно в основной функции?

Это мой метод testNavigation:

var testNavigation = function() 
 
      {     
 
       if ($scope.selections.somethingChanged) { 
 
        
 
        var modal = $modal.open({ 
 
         controller: function ($scope) { 
 
          $scope.okClass = 'btn-primary', 
 
          $scope.okLabel = resourceFactory.getResource('Labels', 'yes'), 
 
          $scope.cancelLabel = resourceFactory.getResource('Labels', 'cancel'), 
 
          $scope.title = resourceFactory.getResource('Labels', 'unsavedChanges'), 
 
          $scope.message = resourceFactory.getResource('Messages', 'unsavedChanges'); 
 
         }, 
 
         templateUrl: '/app/templates/modal' 
 
        }); 
 

 
        modal.result.then(function() { 
 
         
 
         $scope.selections.somethingChanged = false;      
 
         
 
        }); 
 
       } 
 
       
 
       return true; 
 
      }

Я постараюсь, чтобы добавить больше деталей. У меня есть функции LoadView() и New() в контроллере страницы индекса. В обеих этих функциях мне нужно сделать следующее:

if $ scope.selections.somethingChanged = false Мне нужно продолжить логику.

if $ scope.selections.somethingChanged = true Мне нужно выставить модальное диалоговое окно с вопросом, хочу ли я продолжить и отменить изменения или остаться на текущей странице. Если я отвечу «Да», я хочу продолжить логику.

Итак, это цель отдельной функции testNavigation. В тех языках, где каждый вызов функции последователен, это будет работать так, как я предполагал. Но это не работает в AngularJS/JavaScript, и я не уверен, как заставить его работать так, как мне нужно. Мы попробовали несколько идей с помощью сервиса $ q, но не получили результата.

+1

Что такое код внутри 'testNavigation()'. Независимо от того, вам нужно будет использовать обещание (или обратный вызов). –

+1

Вызовите 'testNavigation()', чтобы показать модальный, и иметь отдельный обработчик, Ok ". – tymeJV

+0

Я добавил код для testNavigation. Можете ли вы показать мне, что мне нужно, чтобы изменить его, чтобы достичь моей цели? Еще раз спасибо – Naomi

ответ

2

Сделать testNavigation() всегда возвращает обещание (либо с результатом модальных или с ложным сразу, когда somethingChanged ложно, и вы не хотите, чтобы задать вопрос Действуйте, когда это обещание решить:.

var testNavigation = function() {     
    if ($scope.selections.somethingChanged) {   
     var modal = [...] 
     return modal.result; // returns a promise that will be resolved when the modal is closed 
    } else { 
     return $q.when(true); // returns a promise that will be resolved straight away with true 
    } 
} 

// when used: 

testNavigation().then(function() { 
    ...do stuff... 
}) 
+0

Это решение, по крайней мере, предотвращает состояние гонки, о котором я говорил. –

+0

Спасибо за решение, он отлично работает. – Naomi

0

Не зная, как выглядит ваш тест, это довольно сложно, но из-за этого вы создаете состояние гонки.

Вы называете testNavigation(), которая всегда возвращает истину, , но из-за $ scope.selections.somethingChanged устанавливается на ложь в какой-то момент в будущем, $ scope.selections.somethingChanged не может завершить до конца этой оценки - так в то время как вы настраиваете $ scope.selections.somethingChanged ложь в testNavigation, он может или не может быть ложным, когда второй, если выполняется:

if(testNavigation() && // returns true no matter what. 
    $scope.selections.somethingChanged // this is changed with a promise within testNavigation. that promise could either complete or not complete before this is evaluated with the if. 
){ 
    return false; 
} 

var testNavigation = function() { 
 
    if ($scope.selections.somethingChanged) { 
 

 
    var modal = $modal.open({ 
 
     // details 
 
    }); 
 

 
    modal.result.then(function() { 
 
     // this is async and could take place any time between {locationA} and never. 
 
     $scope.selections.somethingChanged = false; 
 
    }); 
 
    //{locationA} 
 
    } 
 

 
    return true; 
 
}

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

+0

Это именно то, чего я хочу достичь. Я хочу задать вопрос, и если я отвечу «Да» по этому вопросу, я хочу продолжить. – Naomi

+0

Я не думаю, что это правильно: все это однопоточно, поэтому ничто не может работать «между», оценивая два условия if. – pdenes

+0

@Naomi: вы можете только «продолжить», когда возвращается обратный вызов 'modal.result.then'. Я не уверен, что понимаю, что вы пытаетесь сделать в первом блоке (с if, где вы называете 'testNavigation()'), и почему вы устанавливаете 'somethingChanged' в false ... Если, как вы говорите все, что вы хотите сделать, это задать вопрос, а затем сделать X, если ответ был да, тогда вы не можете просто сделать X в этом 'then' обратном вызове? – pdenes

Смежные вопросы