34

AngularJS を使用して Web アプリを作成しています。アプリは、JSON データを返す URL をポーリングし、そのデータをアプリの任意の部分で利用できるようにする必要があります。これまでに読んだことから、私の最善の策は、ポーリングを処理し、JSON データの独自の内部キャッシュを保持するサービスを作成し、そのデータを調べたいアプリの任意の部分にサービスを挿入することです。私が迷っているのは、実際にそれを行う方法です。私が見つけた最も近い例はこの質問ですが、特定のコントローラー (それ自体が特定のルートに関連付けられている) によって手動で呼び出されるサービスを作成しているように見えますが、アプリのバックグラウンドで永続的に実行されるものが必要ですアプリのどの部分がアクティブであるかに関係なく、永久に。これは実行可能ですか、それとも完全に間違ったアプローチをとっていますか?

4

3 に答える 3

41

ここで私の解決策:

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

(ポーリングが完了したことを示すためだけに呼び出します)

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

編集: Josh David Miller がコメントで提案したように、このサービスへの依存関係を app.run ブロックに追加して、ポーリングが最初から確実に行われるようにする必要があります。

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

また、前の通話が終了した後に次のポーリングのスケジュールを移動しました。そのため、ポーリングが長時間ハングした場合に備えて、呼び出しが「スタック」することはありません。

プランカーを更新しました。

于 2013-02-18T21:08:00.127 に答える
21

これは、コントローラーに簡単に挿入できる Githubのangular ポーラー サービスです。

インストールするには: bower install angular-poller.

バックグラウンドで永久に実行されるグローバル ポーリング サービスを開始するには、次のようにします。

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

myPoller.stop()これで、またはを呼び出すまで、バックグラウンドで永久に実行されますpoller.stopAll()

このポーラーのコールバック データを他のコントローラーで使用する場合は、次のように簡単に実行できます。

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);
});
于 2014-01-03T22:47:01.243 に答える