2014-10-10 2 views
0

Angular noob здесь. Я создаю приложение, которое нужно опросить URL-адрес каждую секунду, и сохраняйте эти данные настойчиво, так как к ним нужно обращаться несколькими видами/контроллерами.AngularJS - опрос в постоянное хранилище данных

Что я сделал, чтобы обработать это, я передал свой http-запрос на завод, и данные становятся доступными для контроллеров через функции на заводе. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что фабричная функция вызывается перед HTTP-запросом, вызывая ошибки в моем приложении.

Вот код:

App.factory('metrics', function($http){ 
    var service; 
    var users = [{laps:[]}]; 
    var updateMetrics = function(){ 
     //updates the users array in the factory 
    }; 
    $http.get('data.csv').success(function(data) { 
     var temp_array = data.split(" "); 
     updateMetrics(0, temp_array); 
    }); 

    service.lastLapInfo = function(){ 
     var lastlap = []; 
     for (var i=0; i<users.length;i++) 
     { 
      var lap = users[i].laps[users[i].laps.length-1]; 
      lastlap.push(lap); 
     } 
     return lastlap; 
    }; 
    return service; 
}); 

App.controller('mainController', function($scope, $http, metrics) { 
    $scope.users=metrics.lastLapInfo(); 
}); 

lastLapInfo() становится вызывается перед запросом HTTP, который вызывает ошибки, поскольку нет никаких данных в массиве. Есть предположения?

Дополнительно - если я вообще ошибаюсь, чтобы удовлетворить мой прецедент (например, я должен использовать что-то другое вместо Factory), дайте мне знать!

+0

делает этот материал в обратном вызове успеха, когда у вас действительно есть данные. – dandavis

ответ

2

Это типичный вариант использования обещаний или углового $q service.

Следующий подход, использует завод, который возвращает обещание:

App.factory('metrics', function($http){ 
    var service; 
    ... 
    service.load = function() { 
     return $http.get('data.csv'); 
    }); 
    return service; 
});  

В контроллере вы тогда называете метрики обслуживания, и вы используете обещание:

App.controller('mainController', function($scope, $http, metrics) { 
    metrics.load().then(function(response) { 
     // at this point you know for sure that the request has terminated 
     // you can call the service again to run lastLapInfo or do the logic in here. 
    }); 
}); 
+0

Очень круто! Расширение этого, как я могу настроить настройку этого HTTP-запроса для опроса каждую секунду? Думаю, что я могу подумать, что на заводе должна быть другая функция, например update(), и вызывать эту функцию с определенным интервалом с каждого из моих контроллеров с использованием фабрики. Есть ли способ лучше? – darudude

+0

вы можете использовать услугу $ interval для повторной загрузки метода загрузки в вашу службу. Это далее объясняется здесь: http://stackoverflow.com/questions/14944936/angularjs-global-http-polling-service?answertab=votes#tab-top с примером здесь http://plnkr.co/edit/iMmhXTYweN4IrRrrpvMq ? р = предварительный просмотр. – bengro

+0

Спасибо! Это то, что мне нужно – darudude

1

Если у вас нет данных сразу, либо иметь дело с этим, указав его в возвращаемом значении (null, undefined, []), или return a promise вместо этого, который вы хотите хранить и решить позже, после извлечения данных первоначально.

Так что-то вроде

var deferred = null; 

$http.get(...).then ({ 
    if (deferred) { 
    deferred.resolve(result); 
    deferred = null; 
    } 
}); 

service.lastLapInfo = function(){ 
    if (no metrics) { 
    deferred = $q.defer() 
    return deferred; 
    } 
    else { 
    return metrics; 
    } 
}; 

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

Редактировать: связанный $q с комментария.

+1

Да. Я рекомендую OP посмотреть на AngularJS $ q https://docs.angularjs.org/api/ng/service/$q – Rasmus