获取过滤器来处理承诺的服务

时间:2013-09-13 17:23:40

标签: javascript angularjs

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

基本模式

以下是细分:

  1. 在模块中定义一个返回promise而不是object

    的服务
    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上的then函数来包装$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;
        });
      };
    }]);
    
  4. 那么有没有办法编写过滤器来解析值?

    用例

    这是我想要实现的简化模式。对于那些好奇的人,我的实际用例是预取i18n / l10n资源包信息,这样我就可以本地化我的应用程序中的所有文本。预取都可以在Javascript环境中(附加到一些已经加载的全局或提供程序中),但我们也有数据库存储资源包的场景,所以我需要一个可以预取所有信息的代码版本从服务器通过AJAX。

1 个答案:

答案 0 :(得分: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') }}

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

如果可能的话,使用过滤器完成同样的工作仍然会很好。