AngularJS:异步初始化过滤器 [英] AngularJS : Asynchronously initialize filter

查看:24
本文介绍了AngularJS:异步初始化过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试使用异步数据初始化过滤器时遇到问题.

I'm having trouble trying to initialize a filter with asynchronous data.

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

The filter is very simple, it needs to translate paths to name, but to do so it needs a correspondance array, which I need to fetch from the server.

我可以在返回函数之前在过滤器定义中做一些事情,但异步方面阻止了这一点

I could do things in the filter definition, before returning the function, but the asynchronous aspect prevents that

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

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

使用承诺可能是可行的,但我对角度负载如何过滤没有任何明确的了解.这个帖子解释了如何通过服务实现这种魔力,但是否有可能对过滤器做同样的事情吗?

Using a promise may be viable but I don't have any clear understanding on how angular loads filters. This post explains how to achieve such magic with services, but is it possible to do the same for filters?

如果有人对如何翻译这些路径有更好的想法,我会全力以赴.

And if anyone has a better idea on how to translate those paths, I'm all ears.

我尝试使用 promise approch,但有些地方不对,我看不出是什么:

I tried with the promise approch, but something isn't right, and I fail to see what:

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

我对 Promise 不是很熟悉,这是正确的使用方式吗?

I'm not really familliar with promises, is it the right way to use them?

推荐答案

这是一个例子:

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

这个 fiddle 是一个使用超时而不是服务的演示.

This fiddle is a demonstration using timeouts instead of services.

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

As per the comment of sgimeno, extra care must be taken for not calling the service more than once. See the serviceInvoked changes in the code above and the fiddles. See also forked fiddle with Angular 1.2.1 and a button to change the value and trigger digest cycles: forked fiddle

编辑 2:根据 Miha Eržen 的评论,此解决方案对 Angular 1.3 没有记录器工作.解决方案几乎是微不足道的,使用 $stateful 过滤器标志,记录在 here 在有状态过滤器"下,以及必要的分叉小提琴.

EDIT 2: As per the comment of Miha Eržen, this solution does no logner work for Angular 1.3. The solution is almost trivial though, using the $stateful filter flag, documented here under "Stateful filters", and the necessary forked fiddle.

请注意此解决方案会影响性能,因为过滤器在每个摘要循环中都会被调用.根据具体情况,性能下降可以忽略不计.

Do note that this solution would hurt performance, as the filter is called each digest cycle. The performance degradation could be negligible or not, depending on the specific case.

这篇关于AngularJS:异步初始化过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆