创建一个返回远程数据的角度过滤器?

时间:2015-05-06 20:49:36

标签: angularjs filter angularjs-filter

我有一段经常使用的代码片段,它调用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返回正确的值时,我在页面上看不到它。我猜这是一个时间问题。我可以做些什么来使这项工作,然后在页面上填充值?

3 个答案:

答案 0 :(得分:3)

  

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

每当你听到自己说认为服务不过滤时。虽然理论上你 可以让你的过滤器进行远程调用,但是过度使用过滤器可能会非常低效(可能导致你的页面变慢,甚至可能使你的服务器DDoS)。

您的模式应该更像

{{ returnUserName(userId) }}

或者甚至可能在某处预先计算机用户名,然后再做

{{ userName }}

答案 1 :(得分:1)

只是回答你的问题,这里有一段应该回答你问题的代码片段。 如果你使用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

我希望它会帮助你。

答案 2 :(得分:0)

正如@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/

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