在Angular deferred promise中查找并​​返回项目

时间:2016-04-08 16:09:32

标签: angularjs promise iteration deferred

所以我对角度承诺有点混乱。

我有一项服务,存储用户列表

h = {"extractorData"=>{"url"=>"http://testwebsite.com/", "resourceId"=>"409417ee21618b70d74b03231a793c2d7", "data"=>[{"group"=>[{"image"=>[{"src"=>"test0.jpg"}]}, {"image"=>[{"src"=>"test1.jpg"}]}, {"image"=>[{"src"=>"test2.jpg"}]}, {"image"=>[{"src"=>"test3.jpg"}]}, {"image"=>[{"src"=>"test4.jpg"}]}]}]}}
h.dig('extractorData', 'data').collect{|h| h.dig('group').collect{|h| h.dig('image').collect{|h| h.dig('src')}}}
=> [[["test0.jpg"], ["test1.jpg"], ["test2.jpg"], ["test3.jpg"], ["test4.jpg"]]]

注入后,我可以在控制器中加载我的列表:

.service('user', ['$q','$http', function ($q, $http) {
 var services = {};

 var _def_userLsit = $q.defer();

 $http.get('/api/acc/getlist').then(function (data) {
    _def_userLsit.resolve(data);
 })

 services.getUserListQ = function () {
    return _def_userLsit.promise;
 }
 return services;
}])

这里没问题,在$ scope中得到了json,然后观察者做好了他们的工作。

以下是针对该问题简化的Json格式:

obj 1 {id = 4,userName =“foohuman”,$$ hashKey =“object:14”}    obj 2 {id = 444,userName =“barhuman”,$$ hashKey =“object:22”}

但是我也想要一个id的用户名,我需要多次运行(取决于帖子数)。

所以我的问题是,如何从承诺列表中返回用户名,如函数调用。

像普通函数一样,像这样:

            user.getUserListQ().then(function (promise) {
            $scope.userHelper.userList = promise.data;
        });

如果我只是通过userHelper.userList进行迭代,如果它运行得太早,它可能是空的,所以我需要加载一个承诺,但加载它,迭代槽,然后向$ scope添加一个字符串不是最佳选项,因为它可以运行多次,所以它可以相互覆盖,如果我将它存储在一个变量中,那就非常不可预测了。

所以任何想法我怎么能通过id返回一个很好的简单字符串,而不是一个承诺?

编辑:好的,所以我不能真正返回一个很好的字符串,因为它必须是某种回调,但我可以处理来自promise的数据,所以我最终将用户数据加载到这样的数组中:

$scope.getUserById = function(  id ){
  return "foo";
  //some magic needed here
}

在html中我可以大胆地写 user.getUserListQ().then(function (promise) { var uArr = []; angular.forEach(promise.data, function ( value, key ) { uArr[value.id] = value.userName; }) $scope.userHelper.uArr = uArr; });

1 个答案:

答案 0 :(得分:1)

首先,使用explicit construction antipattern,你的承诺比应有的更难。您的第一个代码段可以替换为:

.service('user', ['$q','$http', function ($q, $http) {
    var services = {};

    var pUserList = $http.get('/api/acc/getlist');

    services.getUserListQ = function () {
        return pUserList;
    };

    return services;
}]);

关于你的问题:

  

所以任何想法我怎么能通过id返回一个很好的简单字符串,而不是一个承诺?

这是错误的心态。为了通过他们的ID获取用户,您需要考虑承诺。您不确切知道数据何时准备好,因此这意味着您的getUserId方法应该返回一个承诺。你可以这样写:

services.getUserById = function (id) {
    return pUserList.then(function (users) {
        return users.filter(function (user) { return user.id === id; })[0];
    });
};

在你的控制器中,你可以像这样使用它:

myService.getUserById(4).then(function (user) {
    $scope.myUser = user;
});