在父控制器

时间:2015-11-04 14:08:26

标签: angularjs

我有以下HTML结构:

<div ng-controller="MainController">
   <div ng-repeat="row in rows">
      [[row.id]]
   </div>
   <div ng-controller="SubController">
      <div ng-repeat="row in rows">
         [[row.id]]
      </div>
   </div>
</div>

角度代码是:

myApp.controller('MainController', function ($scope, $http) {
   $http.get('/foo/ajaxGetSomeData/').then(function (response) {
      $scope.rows = response.data;
   });
});
myApp.controller('SubController', function ($scope, $http) {
   $http.get('/bar/ajaxGetAnotherThing/').then(function (response) {
      var parentRows = $scope.$parent.rows;
      var newRows = parentRows.merge(response.data);
      $scope.rows = newRows;
   });
});

这里的问题是有时第一个请求在第二个请求之后执行。第二个取决于第一个,所以我收到了错误。

我怎么解决这个问题?

1 个答案:

答案 0 :(得分:1)

下面详细阐述我的评论。这里我们将初始化DataRows服务中的两个promise(通过从MainController调用initData)。 SubController不再依赖于MainController,而是依赖于其他东西调用initData的事实。如果其他东西没有调用该函数,那么在未定义的对象上调用“then”时会出现控制台错误。

我还使用$ timeout而不是$ http来模拟异步工作。我不知道你的数据是什么样的,所以我只做了一个字符串数组,你应该能够适应。

angular.module('myApp', [])

// Using $timeout instead of $http for demo
.service('DataRows', function ($http, $q, $timeout) {
    var someData,
        anotherThing;

    this.initData = function () {
        // actual call. get rid of $timeout line in actual code
        // someData = $http.get('/foo/ajaxGetSomeData/').then(function (response) {
        someData = $timeout(function () { return {data: ['parentRow1', 'parentRow2', 'parentRow3']}; }, 1500).then(function (response) {
          return response.data;
           });

           anotherThing = someData.then(function (parentRows) {
               // actual call. get rid of $timeout line in actual code
            // return $q.all([parentRows, $http.get('/bar/ajaxGetAnotherThing/')]);
            return $q.all([parentRows, $timeout(function () {return {data: ['childRow1', 'childRow2', 'childRow3']}}, 1500)]);
           }).then(function (promises) {
               var parentRows = promises[0],
                   response = promises[1];

               // from your original code -- merge is not available here. Mocking concatted rows from first call
               // return parentRows.merge(response.data);
               return parentRows.concat(response.data);
           });
    };

    this.getSomeData = function () {
        return someData;
    };

    this.getAnotherThing = function () {
        return anotherThing;
    };
})

.controller('MainController', function ($scope, DataRows) {
    // initData first so both promises are ready
    DataRows.initData();
  
    // getSomeData is the first promise (call to /foo/ajaxGetSomeData)
    DataRows.getSomeData().then(function (rows) {
        $scope.rows = rows;
    });
})

.controller('SubController', function ($scope, DataRows) {
    // getAnotherThing is the second promise that depends on the first (/bar/ajaxGetAnotherThing)
    DataRows.getAnotherThing().then(function (newRows) {
        $scope.rows = newRows;
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainController">
   <div ng-repeat="row in rows">
      {{row}}
   </div>
   <div ng-controller="SubController">
      <div ng-repeat="row in rows">
         {{row}}
      </div>
   </div>
</div>