2016-01-07 3 views
2

У меня есть следующий пример кода в моем обучающем приложении. Служба выполняет свою работу и вытаскивает некоторые данные из страницы с json-кодом, созданным php, настолько хорошим.

обслуживания:

(function() { 
    'use strict'; 

    angular 
     .module('app.data') 
     .service('DashboardService', DashboardService); 

    DashboardService.$inject = ['$http']; 
    function DashboardService($http) { 

     this.getFormules = getFormules; 

     //////////////// 

     function getFormules(onReady, onError) { 
      var formJson = 'server/php/get-formules.php', 
       formURL = formJson + '?v=' + (new Date().getTime()); // Disables cash 

      onError = onError || function() { alert('Failure loading menu'); }; 

      $http 
       .get(formURL) 
       .then(onReady, onError); 
     } 

    } 
})(); 

Тогда я вызвать функцию getFormules в моем контроллере и поместить все данные в моем $ scope.formuleItems и испытание, если все удалось и «о нет» ... $scope.formuleItems = undefined! - Странно, потому что мой взгляд показывает данные?

часть контроллера:

dataLoader.getFormules(function (items){ 

     $scope.formuleItems = items.data; 

    }); 

    console.log('+++++++++++++++++', $scope.formuleItems); // gives undefined 

Первое, что я сделал поиск вокруг на StackOverflow, чтобы посмотреть, если кто-то еще была такая же проблема, и там было: Undefined variable inside controller function.

Я знаю, что для этого есть несколько путей, я провел собственное исследование, но что-то говорит мне, что это (см. Пример ниже) не лучший способ решить эту проблему.

решение один: поставить $ смотреть внутри контроллера

$scope.$watch('formuleItems', function(checkValue) { 
    if (checkValue !== undefined) { 
    //put the code in here! 
    } 
} 

или даже:

if($scope.formuleItems != null) {} 

Остальная часть контроллера полагается на $ scope.formuleItems. Неужели мне нужно все это положить в $watch или if? Могу ли я исправить это с обещанием? Я никогда этого не делал, поэтому некоторая помощь была бы оценена.

+0

Javascript выполняется асинхронно. Откуда вы знаете, что ваша функция, которая устанавливает это значение, запускается до вашего журнала на консоль? Есть хороший вопрос, который охватывает это, но я не могу найти его в настоящее время. Однако это то, что вам нужно прочитать. Нашел это: http://stackoverflow.com/questions/14220321/how-do-return-the-response-from-an-asynchronous-call –

+3

Предлагаю вам прочитать http: //blog.ninja-squad.com/2015/05/28/angularjs-promises /, в котором описываются, среди прочего, две ловушки об угловых обещаниях, в которые вы попали: не понимая асинхронность и передавая функции обратного вызова, а не пропускать что-либо и возвращать обещание. –

+0

Ничего себе, JB Nizet, какой урок! давайте держим это близко и прочитаем его несколько раз, пока я действительно не пойму. – Peter

ответ

1

код в ваш обратный вызов

function (items){ 
    $scope.formuleItems = items.data; 
} 

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

console.log('+++++++++++++++++', $scope.formuleItems); // gives undefined 

В этот момент обратного вызова еще не был вызван, потому что это занимает некоторое время, и может произойти в любой момент. Для этого выполнение не останавливается. Поэтому значение $ scope.formuleItems по-прежнему не определено, конечно.

После этого - в какое-то определенное время в будущем (возможно, несколько миллисекунд позже) будет вызван обратный вызов, и значение $ scope.formuleItems будет изменено. Вы должны зарегистрировать значение INSIDE вашей функции обратного вызова.

Вам срочно нужно понять эту концепцию, если вы хотите добиться успеха в JavaScript, так как это происходит снова и снова :)

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