【问题标题】:Create an angular filter that returns remote data?创建一个返回远程数据的角度过滤器?
【发布时间】:2015-05-06 20:49:35
【问题描述】:

我有一段我经常使用的 sn-p 代码,它调用 API 以根据发送给它的 ID 返回用户名。

 GetUserNames.get({users: user}, function (data) {
                $scope.userName = data[0];
             })

我想做的就是把它变成一个过滤器,我可以在其中做类似的事情

{{userID | returnUserName}} 

这样我就可以重复使用并保持我的控制器和视图干净。我写了这样的东西:

angular.module('app.filters').filter('returnUserName', function(GetUserNames) {
    return function(input) {
      GetUserNames.get({ users: input }, function (data) {
          console.log(data[0])
          return data[0]

      }); 
     }
});

虽然console.log 返回正确的值,但我在页面上看不到它。我猜这是一个时间问题。我可以做些什么来完成这项工作,以便在页面上填充该值?

【问题讨论】:

  • 有趣的问题,但我认为您需要的是指令,而不是过滤器。 stackoverflow.com/questions/19864318/…
  • 这不是过滤器的用途。它们本质上用于格式化
  • 这是工厂代码,不是过滤器。将缓存设置为 true,并且在第一次调用后立即可用,而无需为需要它的每个控制器发出请求。另外,您在回调中返回到哪里?无处。你的外部函数什么都不返回

标签: angularjs filter angularjs-filter


【解决方案1】:

我有一段我经常使用的代码

每当您听到自己说想服务而不是过滤器时。虽然您可以在理论上让您的过滤器进行远程调用,但这是对过滤器的严重滥用,并且可能会非常低效(可能导致您的页面变慢,甚至可能导致您的服务器遭受 DDoS 攻击)。 p>

你的模式应该看起来更像

{{ returnUserName(userId) }}

或者甚至可以在某处预先计算用户名,然后就这样做

{{ userName }}

【讨论】:

  • 上面那个看起来很干净---我以前没有用过这种方式的服务。我可以从工厂调用我的资源工厂 (GetUserNames) 吗?
  • @Ortal 你可以在任何地方使用它,只需将其列为依赖项
【解决方案2】:

只是为了回答您的问题,这里有一段代码可以回答您的问题。 如果你使用 Angular 1.3.X,你可以使用 $stateful like :

angular.module('app.filters').filter('returnUserName', function($http) {
  var data = null, serviceInvoked = false;

  function realFilter(value) {
      return data;
  }

  filterStub.$stateful = true;
  function filterStub(value) {
    if( data === null ) {
        if( !serviceInvoked ) {
            serviceInvoked = true;
            $http.get('/url/test/').then(function (res) {
                data = res;
            });
        }
        return "";
    }
    else return realFilter(value);
  }
   return filterStub;
});

欲了解更多信息:here

希望对你有帮助。

【讨论】:

    【解决方案3】:

    正如@Florian Orpeliere 提到的,您可以使用有状态过滤器 - 并另外使用一些缓存变量:

        angular.module("app").filter('svcData', function($http) {
            var cached = {};
            var apiUrl = 'http://my.service.com';
            function svcDataFilter(data_id, data_prop) {
                if (data_id) {
                    if (data_id in cached) {
                        // avoid returning a promise!
                        return typeof cached[data_id].then !== 'function' ?
                            cached[data_id][data_prop] : undefined;
                    } else {
                        cached[data_id] = $http({
                            method: 'GET',
                            url: apiUrl + data_id
                        }).success(function (data) {
                                cached[data_id] = data;
                            });
                    }
                }
            }
            svcDataFilterFilter.$stateful = true;
            return svcDataFilterFilter;
    })
    

    并像这样使用它:{{data_id |svcData:'property'}}

    注意:函数 svcDataFilter 将在每个摘要周期被调用。

    此外,如果缓存变得太大,您需要想办法重置缓存。

    见:https://glebbahmutov.com/blog/async-angular-filter/

    而plunker(上面的链接不会显示,所以这里是直接链接):http://plnkr.co/edit/EK2TYI1NZevojOFDpaOG?p=preview

    【讨论】:

      猜你喜欢
      • 2013-12-15
      • 1970-01-01
      • 2015-04-17
      • 2017-11-20
      • 2022-01-03
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多