一尘不染

AngularJS:异步初始化过滤器

angularjs

我在尝试使用异步数据初始化过滤器时遇到麻烦。

过滤器非常简单,它需要将路径转换为名称,但是这样做需要一个对应数组,我需要从服务器中获取该数组。

在返回函数之前,我可以在过滤器定义中执行操作,但是异步方面阻止了该操作

angular.module('angularApp').
  filter('pathToName', function(Service){
    // Do some things here

    return function(input){
      return input+'!'
    }
  }

使用诺言可能是可行的,但我对角负载如何过滤没有明确的了解。这篇文章解释了如何通过服务实现这种魔力,但是是否有可能对过滤器做同样的事情?

而且,如果有人对如何翻译这些路径有更好的主意,我将不知所措。

编辑:

我尝试了Promise方式,但是有一些不对劲,而我却看不到:

angular.module('angularApp').filter('pathToName', function($q, Service){

  var deferred = $q.defer();
  var promise = deferred.promise;

  Service.getCorresp().then(function(success){
    deferred.resolve(success.data);
  }, function(error){
    deferred.reject();
  });

  return function(input){
    return promise.then(
      function(corresp){
        if(corresp.hasOwnProperty(input))
          return corresp[input];
        else
          return input;
      }
    )
  };
});

我不是很熟悉诺言,使用诺言是否正确?


阅读 470

收藏
2020-07-04

共1个答案

一尘不染

这是一个例子:

app.filter("testf", function($timeout) {
    var data = null, // DATA RECEIVED ASYNCHRONOUSLY AND CACHED HERE
        serviceInvoked = false;

    function realFilter(value) { // REAL FILTER LOGIC
        return ...;
    }

    return function(value) { // FILTER WRAPPER TO COPE WITH ASYNCHRONICITY
        if( data === null ) {
            if( !serviceInvoked ) {
                serviceInvoked = true;
                // CALL THE SERVICE THAT FETCHES THE DATA HERE
                callService.then(function(result) {
                    data = result;
                });
            }
            return "-"; // PLACEHOLDER WHILE LOADING, COULD BE EMPTY
        }
        else return realFilter(value);
    }
});

这个小提琴是一个使用超时而不是服务的演示。


编辑:根据sgimeno的评论,必须格外小心,不要多次致电该服务。请查看serviceInvoked上面代码中的更改和小提琴。另请参阅Angular
1.2.1的分叉小提琴和一个用于更改值并触发摘要循环的按钮:分叉小提琴


编辑2:根据MihaEržen的评论,此解决方案对Angular1.3没有记录程序。该解决方案几乎是微不足道的,虽然,使用$stateful过滤器标志,记录在这里下的“状态过滤器”,以及必要的分叉小提琴

请注意 ,此解决方案会损害性能,因为每个摘要循环都称为过滤器。根据具体情况,性能下降是否可以忽略不计。

2020-07-04