Sto costruendo un'app Web utilizzando AngularJS. L'app deve eseguire il polling di un URL che restituisce i dati JSON e rendere tali dati disponibili per qualsiasi parte dell'app. Da quanto ho letto fino ad ora, la mia migliore scommessa è creare un servizio che gestisca il polling e conservi la propria cache interna dei dati JSON, e quindi iniettare il servizio in qualsiasi parte dell'app che desideri consultare tali dati. Quello su cui mi sono perso è come farlo davvero. L'esempio più vicino che ho trovato è this question, ma sembra che stia creando un servizio che viene chiamato manualmente da un controller specifico (che è esso stesso legato a una determinata route), mentre voglio qualcosa che viene eseguito costantemente sullo sfondo dell'applicazione per sempre indipendentemente da quale parte dell'app è attiva. È fattibile, o sto prendendo l'approccio completamente sbagliato?Servizio di polling HTTP globale di AngularJS
risposta
Ecco la mia soluzione:
app.factory('Poller', function($http, $timeout) {
var data = { response: {}, calls: 0 };
var poller = function() {
$http.get('data.json').then(function(r) {
data.response = r.data;
data.calls++;
$timeout(poller, 1000);
});
};
poller();
return {
data: data
};
});
(chiamate solo a dimostrare che il polling è stato fatto)
http://plnkr.co/edit/iMmhXTYweN4IrRrrpvMq?p=preview
EDIT: Come Josh David Miller ha suggerito nei commenti, dipendenza da questo il servizio deve essere aggiunto nel blocco app.run per garantire che il polling venga eseguito dall'inizio:
app.run(function(Poller) {});
E anche spostato la pianificazione del prossimo sondaggio al termine della chiamata precedente. Quindi non ci sarebbe "stacking" di chiamate nel caso in cui il polling si blocca per un lungo periodo.
Plunker aggiornato.
Questo è un angular poller service su Github che può essere facilmente inserito nel controller.
Per installare: bower install angular-poller
.
Dal momento che si desidera avviare un servizio di polling globale che viene eseguito in background per sempre, si può fare:
// Inject angular poller service.
var myModule = angular.module('myApp', ['poller']);
// The home/init controller when you start the app.
myModule.controller('myController', function($scope, $resource, poller) {
// Define your resource object.
var myResource = $resource(url[, paramDefaults]);
// Create and start poller.
var myPoller = poller.get(myResource);
// Update view. Most likely you only need to define notifyCallback.
myPoller.promise.then(successCallback, errorCallback, notifyCallback);
});
Ora verrà eseguito in background per sempre fino a quando si chiama myPoller.stop()
o poller.stopAll()
.
Se si desidera utilizzare i dati di callback di questo poller in altri controller, si può semplicemente fare:
myModule.controller('anotherController', function($scope, $resource, poller) {
/*
* You can also move this to a $resource factory and inject it
* into the controller so you do not have to define it twice.
*/
var sameResource = $resource(url[, paramDefaults]);
/*
* This will not create a new poller for the same resource
* since it already exists, but will simply restarts it.
*/
var samePoller = poller.get(sameResource);
samePoller.promise.then(successCallback, errorCallback, notifyCallback);
});
Sembra una grande biblioteca. C'è una app di esempio qualcosa là fuori? – ardochhigh
@ardochhigh Ho intenzione di aggiungere presto un'app campione. Ma prima che ciò accada, puoi controllare la pagina [readme] (https://github.com/emmaguo/angular-poller/blob/master/README.md). :-) –
Grazie a @Emma Guo la pagina README è abbastanza dettagliata. Sono abbastanza nuovo per Angular e sono ancora in difficoltà con alcuni concetti. La tua libreria sembra perfetta per le mie esigenze. Forse cercherò di fare un plunker per una dimostrazione di concetto. Ti farò sapere. – ardochhigh
ho biforcato @ codice di fabbrica di ValentynShybanov e ha aggiunto intervalli chiamate (ogni secondo, ogni 5 secondi, ecc), inoltre è possibile arrestare e avviare il poller come si desidera:
http://plnkr.co/edit/EfsttAc4BtWSUiAU2lWf?p=preview
app.factory('Poller', function($http, $timeout) {
var pollerData = {
response: {},
calls: 0,
stop: false
};
var isChannelLive = function() {
$http.get('data.json').then(function(r) {
if (pollerData.calls > 30 && pollerData.stop === false) { // call every minute after the first ~30 secs
var d = new Date();
console.log('> 30: ' + d.toLocaleString() + ' - count: ' + pollerData.calls);
pollerData.calls++;
$timeout(isChannelLive, 10000);
} else if (pollerData.calls > 15 && pollerData.calls <= 30 && pollerData.stop === false) { // after the first ~15 secs, then call every 5 secs
var d = new Date();
console.log('> 15 & <= 30: ' + d.toLocaleString() + ' - count: ' + pollerData.calls);
pollerData.calls++;
$timeout(isChannelLive, 5000);
} else if (pollerData.calls <= 15 && pollerData.stop === false) { // call every 1 second during the first ~15 seconds
var d = new Date();
console.log('<= 15: ' + d.toLocaleString() + ' - count: ' + pollerData.calls);
pollerData.calls++;
$timeout(isChannelLive, 1000);
}
pollerData.response = r.data;
});
};
var init = function() {
if (pollerData.calls === 0) {
pollerData.stop = false;
isChannelLive();
}
};
var stop = function() {
pollerData.calls = 0;
pollerData.stop = true;
};
return {
pollerData: pollerData, // this should be private
init: init,
stop: stop
};
});
- 1. AngularJS: concatenamento di http promette $ q in un servizio
- 2. AngularJS - metodo di servizio di test che utilizza il servizio di $ http
- 3. Intestazione globale per AngularJS post
- 4. AngularJS: factory $ http service
- 5. Disattivazione AngularJS $ http cache di
- 6. AngularJs: $ http chiamata sincrona
- 7. Tempi Angularjs con un filtro e un servizio $ http
- 8. Oggetto servizio orologio Angularjs
- 9. Servizio AngularJS Passaggio di dati tra controllori
- 10. AngularJS modificano a livello globale l'URL di ogni richiesta a $ http
- 11. Configurazione globale $ http per l'utilizzo di CORS in angularJS (dominio fisso per tutte le richieste)
- 12. AngularJS: posizione corretta per il provider globale di menu, servizio o rootScope?
- 13. Non inquinante globale con angularjs
- 14. AngularJS servizio eredità emette
- 15. Servizio AngularJS riutilizzabile all'interno di un'app
- 16. Impostazione angularjs $ http headers globalmente
- 17. AngularJS comprime $ post http dati
- 18. AngularJS, $ http e transformResponse
- 19. AngularJS: decorazione $ http
- 20. Come faccio a simulare $ http nel servizio Jasmine del servizio AngularJS?
- 21. AngularJS $ http indefinito
- 22. Direttive di compilazione tramite servizio in angularjs
- 23. AngularJs 2: più istanze di servizio create
- 24. iniezione condizionale di un servizio in AngularJS
- 25. AngularJS - Direttiva CRUD/schemi di servizio/controller
- 26. AngularJS - creazione di un oggetto servizio
- 27. AngularJS servizio eredità
- 28. Ignora servizio AngularJs
- 29. polling vs polling lungo
- 30. dati servizio chiaro in AngularJs
+1 ma vuole qualcosa di correre sempre, in modo da scatenare da un 'app.run' blo ck per assicurarti che funzioni dall'inizio. Vorrei anche controllare la funzione 'poller' per garantire che la precedente chiamata a $ http' completata in modo che non si accumulasse all'infinito, ma sembra che non ci sia modo di farlo con l'implementazione della promessa di AngularJS. –
Thnx. Aggiunti entrambi gli elementi in risposta. E per quanto riguarda lo stacking potrebbe essere evitato spostando semplicemente la pianificazione del prossimo sondaggio in "then" della precedente chiamata. Non è vero? –
Fantastico! :-) Credo di essere stato così concentrato sul metodo originale di 'q' di' isFulfilled() 'che' $ q' non implementa quello che mi è sfuggito del tutto ovvio. lol –