1

私はすでにこのコードを同期的に動作するように作り直し始めていますが、好奇心と両方の手段をサポートしたいという願望から、フィルターをプロミスでジャイブする方法を理解する助けが必要です。他の投稿で言及されているように、フィルターはプロミスから {} に解決されるようです。

基本パターン

内訳は次のとおりです。

  1. オブジェクトの代わりに promise を返すモジュールでサービスを定義する

    module.factory('promisedSvc', ['$http', function($http) {
    
      var httpPromise = null,
        servicePromise = null,
        service = {},
        dataSet = {};
    
      var httpPromise = $http.get('somedata.json').success(function(data) {
        dataSet = data;
      });
    
      servicePromise = httpPromise.then(function(){
        service.getData = function(key) {
          return dataSet[key];
        };
    
        service.addData = function(key, value) {
          dataSet[key] = value;
        };
    
        return service;
      });
    
      /*
        In actuality I proxied the service methods onto the promise because
        I didn't want consumers of the service to have to deal with it being
        a promise. There is the caveat of setting properties on a class I 
        don't own (property collisions), a risk I'm okay taking, but YMMV
    
        Commented out proxies
        servicePromise.getData = function(key) {
          return this.then(function(svc){
            return svc.getData(key);
          });
        };
    
        servicePromise.addData = function(key, value) {
          this.then(function(svc){
            svc.addData(key, value);
          });
        };
      */
    
      return servicePromise;
    }]);
    
  2. コントローラーはこのpromisedSvc問題を処理できます。コントローラーに注入された promise を取得し、promise で関数を使用して、プロパティの設定を最終的なサービス オブジェクトの関数呼び出しにthenラップするだけです:または. または、コメントアウトされたブロックのように関数をプロミスにプロキシした場合は、通常どおりに処理できます。$scopegetData(key)setData(key, value)

  3. フィルターは本質的にプロミスを処理するようには見えません$scope。フィルターに注入して、約束がまだ解決されていないため、解決せずpromisedSvcに呼び出すことができるようにする方法を探しています。以下は、うまくいかない例です。getData(key){}

    module.filter('svcData', ['promisedSvc', function(promisedSvc) {
      return function(input) {
    
        return promisedSvc.then(function(svc) {
          var value = svc.getData(input);
          return value;
        });
      };
    }]);
    

値を解決できるようにフィルターを作成する方法はありますか?

使用事例

それは私が達成しようとしていることの単純化されたパターンです。好奇心旺盛な人のために説明すると、私の実際の使用例は、アプリケーション内のすべてのテキストをローカライズできるように、i18n/l10n リソース バンドル情報をプリフェッチすることです。プリフェッチはすべて Javascript 環境 (既にロードされているグローバルまたはプロバイダーにアタッチ) で行うことができますが、データベースに格納されたリソース バンドルを使用するシナリオもあるため、すべての情報をプリフェッチできるコードのバージョンが必要でした。 AJAX経由でサーバーから。

4

1 に答える 1

0

それはまさに私が探しているものではありませんが、少なくとも回避策を文書化するために:

フィルターの代わりに $scope で関数を使用することができます。

module.factory('promisedSvc', ['$http', '$rootScope', function($http, $rootScope) {

  var httpPromise = null,
    servicePromise = null,
    service = {},
    dataSet = {};

  var httpPromise = $http.get('somedata.json').success(function(data) {
    dataSet = data;
  });

  servicePromise = httpPromise.then(function(){
    service.getData = function(key) {
      return dataSet[key];
    };

    service.addData = function(key, value) {
      dataSet[key] = value;
    };

    //Here is the addition to setup the function on the rootScope
    $rootScope.svcData = function(key) {
      return service.getData(key);
    };

    return service;
  });

  return servicePromise;
}]);

そして、代わりにテンプレートで{{ 'key1' | svcData }}使用します{{ svcData('key1') }}

Promiseの解決を遅らせると (たとえば、で待機をセットアップすると$http.success)、ページの読み込みに影響が及ぶことをテストしましたが、svcData 関数からの値は、Promise が解決された後にのみテンプレートに取り込まれます。

可能であれば、フィルターを使用して同じことを達成できればなお良いでしょう。

于 2013-09-13T17:59:44.443 に答える