2014-03-26 35 views
3

我有一个json文件,我从我数据库中的所有人那里获取信息。我实际上使用它来显示网页中的名字,姓氏,我想添加显示每个人的详细信息的可能性。AngularJS:从一个ID为json数组获取数据

要做到这一点我使用的人的ID是这样的:

.when('/people/:id', {templateUrl: 'partials/people-detail.html'}) 

它工作得很好,我对每个人,这是很好的生成的页面。但是现在我想要得到这个人的信息。

最简单的方法应该是为每个人都有一个json文件,但我并不特别喜欢这么多文件的想法。 所以我真正的想法是迭代通过people.json文件找到好的并使用它,但它不工作。

这里是我的控制器:

var PeopleController = angular.module ('PeopleController', []); 

PeopleController.controller('PeopleDetailCtrl', ['$scope', '$routeParams', '$http', 
    function($scope, $routeParams, $http) { 
     $scope.search = function() { 
      var url = 'data/people.json'; 
      $http.get(url).success(httpSuccess).error(function() { 
       alert('Unable to get back informations :('); 
      }); 
     } 
     httpSuccess = function(response) { 
      $scope.persons = response; 
     } 

     function getById(arr, id) { 
      for (var d = 0, len = arr.length; d < len; d += 1) { 
       if (arr[d].id === id) { 
        return arr[d]; 
       } 
      } 
     } 
     $scope.search(); 
     $scope.person = getById($scope.persons,$routeParams.id); 
    }]); 

好吧,也许我的解决方案是坏的,因为它不工作,但我没有找到另一种方式来做到这一点。

现在我都是你的:)

感谢您的阅读。

回答

4

问题是您的$scope.search方法包含$http.get()这是异步的。

这意味着你的下一行(设置为$scope.person的行)执行之前已经读取了json文件。因此,$scope.persons在执行时为空。

您可以利用这个事实$http.get()这里返回一个可链式的promise

所以,如果你改变你的search()函数返回的承诺,你就可以使用then()填充person时,一切都很顺利:

$scope.search = function() { 
    var url = 'data/people.json'; 

    return $http.get(url).success(httpSuccess).error(function() { 
    alert('Unable to get back informations :('); 
    }); 

} 

(注意return语句)。

然后改变人人口利用这一点:

$scope.search().then(function(){ 
    $scope.person = getById($scope.persons,$routeParams.id); 
}); 
+0

感谢您的帮助,它的工作原理!我不知道这是否是最好的解决方案(如果我不得不每次重复1000次,这不是很酷),但它仍然有效。 那么,我真的不明白th​​en()方法的效用。唯一的区别是它等待承诺。即使您不确定success()是否会返回promise,在这种情况下,您将使用error()方法来管理此问题,对吧? – Ryuu

+0

如果它有效,那么成功会回报一个承诺,是的。如果你想了解更多信息,你应该阅读承诺。这是一个有据可查的JavaScript原则。关于您通过ID获取的解决方案:更好的选择是将您的信息存储在数据库而不是json文件中,然后通过在服务器上公开API直接查询数据库。 –

+0

我会搜索一下,谢谢。使用数据库和服务器是我的第一个想法,但应用程序也应该离线工作(移动应用程序与科尔多瓦),所以我选择本地库存一切,并增加了通过询问服务器来更新文件的可能性。 – Ryuu

0

我希望得到一个人就像是在点击一个完全不同的事件。您可以尝试的grep:

$scope.person = function(_id) { 
    return $.grep($scope.persons, function(item){ 
     return item.id == _id 
    })[0]; 
} 

假设你有可用的所有的人,否则这种逻辑有成功的回调HTTP调用的部分内移动。

+0

感谢您的帮助,但我没有使用任何jQuery。 – Ryuu

0

我使用了ECMAScript 5 filter,通过id获取人,并将id由id转移到success方法,因为我们正在处理ajax调用。

例子:

app.controller('PeopleDetailCtrl', ['$scope', '$routeParams', '$http', 
    function($scope, $routeParams, $http) { 
     $scope.search = function() { 
      var url = 'data.json'; 
      $http.get(url).success(httpSuccess).error(function() { 
       alert('Unable to get back informations :('); 
      }); 
     } 
     httpSuccess = function(response) { 
      $scope.persons = angular.fromJson(response); 

      $scope.person = $scope.persons.filter(function(item){ 
      return item.id==routeParams.id //check for undefined; 
      }); 
     } 


     $scope.search(); 

    }]); 

活生生的例子:http://plnkr.co/edit/jPT6aC5UqLdHGJ1Clfkg?p=preview

+0

我认为最好是通过单独的id保持搜索,并返回承诺,就像我的答案一样。这使得使用相同的数据检索功能来执行其他操作变得容易,或者更好地将数据检索迁移到服务。 –

+0

过滤器创建一个数组。 – Chookoos