2014-03-26 73 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