1

我已经开始重新编写此代码以同步操作,但出于好奇和支持这两种方式的愿望,我需要一些帮助来了解如何让过滤器与 promise 配合使用。正如其他一些帖子提到的那样,过滤器似乎只是从承诺中解析为 {}。

基本模式

这是一个细分:

  1. 在模块中定义一个返回承诺而不是对象的服务

    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 注入控制器,然后使用thenPromise 上的函数将属性设置包装$scope到最终服务对象的函数调用中:getData(key)setData(key, value). 或者,如果您像注释掉的块中那样将函数代理到 promise 上,则可以将其视为正常。

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

我测试过,如果您延迟承诺解决(例如在 中设置等待$http.success),影响是页面加载,但是一旦承诺解决,来自 svcData 函数的值只会填充到模板中。

如果可能的话,用过滤器完成同样的事情还是很不错的。

于 2013-09-13T17:59:44.443 回答