angular 控制器中的范围值错误

Wrong value of scope in angular controller

我是 angular 1 的新手,我的代码有问题:

var app = angular.module("Football", []);

app.factory("competitions", ['$http', function($http) {
  return $http.get("json/competitions.json")
  .success(function(response) {

    var data = {
      response: response,
      teams: []
    };

    for (var i = 0; i < response.length; i++) {

      $http.get("json/teams.json")
      .success(function(response2) {
        data.teams.push(response2);
        return data
      })
      .error(function(err) {
        return err;
      });
    }

  })
  .error(function(err) {
    return err;
  });
}]);


app.controller('MainController', ['$scope', "competitions", function($scope, competitions) {
  competitions.success(function(data) {
    $scope.competitions = data;
  });
}]);

我想将数据从竞赛工厂传递到 MainController 中的 $scope.competitions。在 for 循环的最后一次迭代之后 data 变量应该传递给控制器​​。我知道这段代码是错误的,因为它只将响应传递给控制器​​,但我不知道如何修复它。有人可以帮助我吗?

试试这个

    var app = angular.module("Football", []);

app.factory("competitions", ['$http', '$q', function ($http, $q) {
  function getCompetitions(){
    return $http.get('json/competitions.json');
  }
  return {
    get: function(){
      var mainTask = $q.defer();
      getCompetitions().then(function(response){
        var compData = {
          competitions: response.data,
          teams:[]
        }
        var tasks = [];
        for(var i=0;i<compData.competitions.length;i++){
          tasks.push($http.get("json/teams.json"));
        }
        $q.all(tasks).then(function(responses){
          for(var j = 0;j<responses.length;j++){
            compData.teams.push(responses[i]);
          }
          mainTask.resolve(compData);
        }).catch(function(error){
          mainTask.reject(error);
        })
      }).catch(function(error){
        mainTask.reject(error);
      }) 
      return mainTask.promise;
    }
  }
}]);


app.controller('MainController', ['$scope', "competitions", function ($scope, competitions) {
  competitions.get().then(function(data){
    $scope.competitions = data;
  }).catch(function(error){
    //catch error here
  })
}]);

你做错了几件事。

  1. 不再使用.success().error()函数。请改用 .then()

  2. .success()函数有四个参数。第一个是 returned 的数据,所以 response 是实际数据,而不是整个响应。如果您使用 .then(),那么您将得到响应,您可以从中提取数据。

  3. 使用 $q 库来 return 您自己的承诺,而不是 return 从工厂获取数据。您可以在控制器中提取该数据,正如您应该的那样。

  4. 不要 运行 直接从 response 循环,因为你永远不知道它是否是一个数组。如果它是实际响应,它将是实际数据的包装器。

  5. teams.json 承诺中的 returned dataerr 去哪儿了?我猜那部分是空的。

  6. 与代码相比,Promises 需要很长时间才能解决,因此我建议您不要从工厂调用 teams.json,而应从控制器调用。也就是说,在范围内的 ng-repeat 中替换一个虚拟对象,然后当返回此数据时,将实际数据替换为虚拟对象。

我认为针对你的情况的解决方案是首先向比赛提出请求,然后将所有请求分组,然后用 $q.all 解决。 检查以下 jsbin:http://jsbin.com/korenodota/1/edit?html,js,console

var app = angular.module("AngularApp", ['test']);

angular.module('test', [])
  .controller('TestController', ['$scope', 'CompetitionsService', function ($scope, CompetitionsService) {
    $scope.competitions = [];

    CompetitionsService.getCompetititons().then(function (response) {
      $scope.competitions = response;
      console.log($scope.competitions);
    });
  }])
.service('CompetitionsService', ['$q', function($q) {
    var getCompetititons = function() {

       // Replace with your competition's http request
       return $q(function (resolve) {
         return resolve([{
           id: 1,
           competition: 'DUMMY-1'
         }, {
           id: 2,
           competition: 'DUMMY-2'
         }])
       }).then(function (competitions) {
         var promises = competitions.map(function (competition) {

           // Replace with your team's http request
           return $q(function (resolve) {
             var teamBaseName = competition.id;
             competition.teams = [teamBaseName + '1', teamBaseName + '2'];
             return resolve(competition)
           });
         });

         return $q.all(promises);
       });
    };

    return {
      getCompetititons: getCompetititons
    };
}]);

PS:请注意,我没有确切的 http 请求,我只是用返回虚拟数据的正常承诺替换。