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

查看:1076
本文介绍了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.

我可以做的事情在过滤器定义,返回功能之前,但异步方面prevents了

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+'!'
    }
  }

使用的承诺可能是可行的,但我没有对负载如何角器的任何清醒的认识。
这<一个href=\"http://stackoverflow.com/questions/16286605/initialize-angularjs-service-with-asynchronous-data\">post说明如何实现这种神奇的服务,但有可能给过滤器做?

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.

编辑:

我试图与承诺计算策略,但东西是不正确的,我看不出有什么:

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

我不是真正的承诺familliar,它是使用它们的正确方法?

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

小提琴是使用,而不是服务超时示范。

This fiddle is a demonstration using timeouts instead of services.

编辑:按sgimeno的评论,格外小心,必须采取不调用服务一次以上。请参见code以上和小提琴的 serviceInvoked 的变化。请参阅使用角度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:按照米哈Eržen的评论,这种解决方案确实为1.3角没有logner工作。该解决方案几乎是微不足道的,虽然,使用 $状态过滤标志,记录的这里下」,以及必要的分叉小提琴

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天全站免登陆