2013-02-18 20 views
30

AngularJS kullanarak bir web uygulaması yapıyorum. Uygulamanın, JSON verilerini döndüren ve bu verilerin uygulamanın herhangi bir bölümüne erişebildiği bir URL'yi incelemesi gerekiyor. Şimdiye kadar okuduklarımdan, en iyi bahse girme, sorgulamayı işleyen ve JSON verilerinin kendi dahili önbelleğini tutan bir hizmet oluşturmak ve ardından bu verilere başvurmak isteyen uygulamanın herhangi bir bölümüne hizmeti enjekte etmektir. Kaybettiğim şey aslında bunu yapmayı düşünmektir. Bulduğum en yakın örnek this question'dur, ancak belirli bir denetleyici tarafından (kendisiyle belirli bir rotaya bağlı olan) manuel olarak çağrılan bir hizmet oluşturuyor gibi görünmektedir, buna karşın uygulamanın arka planında sürekli olarak çalışan bir şey istiyorum. Uygulamanın hangi bölümünün aktif olduğuna bakılmaksızın. Bu yapılabilir mi yoksa tamamen yanlış yaklaşımı mı ele alıyorum? İşteAngularJS global http oylama hizmeti

cevap

41

benim çözüm:

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 
    }; 
}); 

(çağrılar sadece yoklama yapıldığını olduğunu göstermek için)

http://plnkr.co/edit/iMmhXTYweN4IrRrrpvMq?p=preview

DÜZENLEME: Bu konuda Josh David Miller Yorum önerilen gibi, bağımlılık sorgulamanın başından yapılmasını sağlamak için app.run bloğunda hizmet eklenmelidir:

app.run(function(Poller) {}); 

Ayrıca, önceki çağrı bittikten sonra bir sonraki anketin planlamasını da yaptı. Bu nedenle, yoklama uzun bir süre askıda kaldığında çağrıların "istiflenmesi" olmayacaktır.

Güncelleme plunker.

+2

+1 Ama o şey her zaman çalışan istiyor, aynı zamanda bir 'app.run' bozulmasın onu tetikleyecek Başlangıçtan itibaren çalışmasını sağlamak için ck. Ayrıca, "$ http" 'un daha önceki çağrısının tamamlanmasını sağlamak için "Poller" işlevini de kontrol ediyorum, böylece sadece sonsuz bir şekilde yığılmıyorlar, ancak AngularJS söz uygulamasıyla bunu yapmanın bir yolu yok gibi görünüyor. –

+1

Thnx. Her iki maddeyi de cevaplandı. Ayrıca, bir sonraki yoklamanın programlamasının, önceki aramanın "o zaman" haline getirilmesiyle yığınlama hakkında önlenebilir. Öyle değil mi? –

+1

Harika! :-) Ben q q''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' yerine getirdi. lol –

20

Github'da denetleyicinize kolayca enjekte edilebilen bir angular poller service.

Takmak için: bower install angular-poller. Sonsuza arka planda çalışan bir küresel yoklama hizmetini başlatmak istiyor beri

, yapabileceğiniz: Eğer myPoller.stop() veya poller.stopAll() arayana kadar

// 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); 
}); 

Şimdi sonsuza arka planda çalışır. Diğer kontrolörler bu poller ait geri arama verilerini kullanmak isterseniz

, sadece yapabilirsiniz:

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); 
}); 
+0

Harika bir kütüphaneye benziyor. Orada örnek bir uygulama var mı? – ardochhigh

+0

@ardochhigh Yakında bir örnek uygulama eklemeyi planlıyorum. Ancak bundan önce, [readme] (https://github.com/emmaguo/angular-poller/blob/master/README.md) sayfasını kontrol edebilirsiniz. :-) –

+0

Teşekkür Ederiz Guo README sayfası oldukça ayrıntılı. Ben Angular'a oldukça yeni ve hala bazı kavramlarla mücadele ediyorum. Kütüphane benim gereksinimleri için mükemmel görünüyor. Belki de bir kavram kanıtı için bir plunker yapmaya çalışacağım. Seni bilgilendirecegim. – ardochhigh

0

Ben ValentynShybanov fabrika kodu @ çatallı ve katma aralıkları aramalar (her saniye, her 5 saniye, vs), aynı zamanda durdurup Poller başlatmak istediğiniz gibi yapabilirsiniz:

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 
    }; 
});