角度控制器中范围的错误值

时间:2017-02-11 19:23:18

标签: javascript angularjs angularjs-factory

我是角色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 变量应该传递给控制器​​。我知道这段代码是错误的,因为它只传递对控制器的响应,但我不知道如何修复它。有人能帮助我吗?

3 个答案:

答案 0 :(得分:3)

你在这里犯了一些错误。

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

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

  3. 使用$q库返回您自己的承诺,而不是从工厂返回数据。您可以按照自己的意愿在控制器中提取该数据。

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

  5. 来自data承诺的返回errteams.json在哪里?我猜这个部分是空的。

  6. 与代码相比,Promise需要解决问题,因此我建议您不要从工厂调用teams.json,而是从控制器调用ng-repeat。也就是说,在范围内的O(n^2)内替换一个虚拟对象,然后当这些数据返回时,将实际数据放在虚拟对象的位置。

答案 1 :(得分:0)

试试这个

    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
  })
}]);

答案 2 :(得分:0)

我认为您的案例的解决方案是首先向竞赛提出请求,然后将所有请求分组,然后使用$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请求,我只是用正常的promises替换了虚拟数据。