Angular ng-repeat如何在每个项目的模板中展开promise

时间:2014-08-11 15:53:57

标签: angularjs

过去,功能返回的承诺过去能够绑定到模板,当承诺得到解决时,值会在模板中自动更新。但是,我已经读到这种自愿展开的承诺不再存在。

我在下面提供了简化代码,以便了解我想要做什么。我的控制器有一个包含对象的dataArray。每个对象都包含一个id字段。控制器有一个函数,它接受id并返回一些数据的promise。在模板中,我使用ng-repeat来遍历dataArray中的每个对象(obj),并且我想绑定到getData为每个obj返回的promise的已解析值。但是,当我这样做时,我得到了“10 $ digest()迭代次数。中止!”我读过的错误是由于承诺无法解开而无法再与模板绑定的事实。

控制器:

myApp.controller('myCtrl', function($scope, dataStore) {

  $scope.someDataArray = dataArray;  // an array of objects

  // returns a promise to provide data for the supplied id
  $scope.getData = dataStore.getData(id); 


})

模板:

<div>
  <table>
    <thead>
        ....
    </thead>
    <tbody>
      <tr ng-repeat="obj in dataArray">
        <td>{{obj.item1}}</td>
        <td>{{getData(obj.id)}}</td>
      </tr>
    </tbody>
  <table>
<div>

有没有人有一个很好的方法可以将一个值从ng-repeat中的值数组传递给一个返回一个promise的函数,这样当promise解析时,值会在模板的每个表格单元中更新?

我知道如果我为单个值执行此操作,我可以为范围上的值创建变量,并使用promise的then()函数来设置值。模板将绑定到此值。但是,当我使用ng-repeat时,dataArray中的每个obj.id都会有单独的函数调用。

2 个答案:

答案 0 :(得分:3)

好吧,我个人不认为从视图中拨打电话是一种很好的做法。

我会在视图中将事情分开,绑定到将由已解析的承诺填充的属性:

<div>
  <table>
    <thead>
        ....
    </thead>
    <tbody>
      <tr ng-repeat="obj in dataArray">
        <td>{{obj.item1}}</td>
        <td>{{obj.data)}}</td>
      </tr>
    </tbody>
  <table>
<div>

在我的控制器上,我会为数组的每个项目调用getData(),以使其更好,我会使用手表,所以每次我的阵列更新时我都要确保调用执行getData()

myApp.controller('myCtrl', function($scope, dataStore) {

   $scope.$watch('someDataArray ', function(newArray) {
      for(var i=0; i<newArray.length; i++){
          populateData(newArray[i]);
      }
   });

   var populateData = function(obj){
      dataStore.getData(obj.id).then(function(value){
          obj.data = value;
      });
   }

   $scope.someDataArray = dataArray;  // an array of objects

});

我没有测试过这个,但这是一般的想法。希望有所帮助。

答案 1 :(得分:0)

获取控制器中的数据:

$scope.fetchedData = [];
$q.all($scope.someDataArray.map(function(obj) {
    return dataStore.getData(obj.id);
}).then(function(array) {
    $scope.fetchedData = array;
});

在视图中,显示提取的数据:

<tr ng-repeat="obj in dataArray">
  <td>{{obj.item1}}</td>
  <td>{{ fetchedData[$index] }}</td>
</tr>