解析json数组在angularjs中无法正常工作

时间:2018-08-07 05:52:45

标签: javascript angularjs json for-loop

我有angular js应用程序。我正在尝试使用angular.forEach解析json数组。它显示出奇怪的行为。

当我尝试进行操作时,它会显示数据,但是当我尝试进行长度操作时,它会显示长度为0。

我只想在循环外输出。我该如何实现?

有人可以帮我吗?

function loadRelease() {
    $scope.datas.releaseData = [];
    angular.forEach($scope.datas.repositoryData, function(value, key) {
        GitHubService.getDevMasterReleaseDate(value.url)
            .then(function(responseRepo) {
                var dataToOperate = [];
                var dataJson = {
                    'repoName': value.name
                    , 'masterArray': []
                    , 'devArray': []
                }

                angular.forEach(responseRepo.data, function(value, key) {
                    if (value.target_commitish == 'master') {
                        dataJson.masterArray.push(value);
                    } else {
                        dataJson.devArray.push(value);
                    }
                });

                $scope.datas.releaseData.push(dataJson);
            }, function(error) {

            });

    });
    console.log($scope.datas.releaseData);
    console.log('length :: ' + $scope.datas.releaseData.length);

}

控制台:

http://recordit.co/FfXHww1xCv

4 个答案:

答案 0 :(得分:1)

  

通过引用传递对象/数组,并传递原始值   通过JavaScript中的值。

以下是对异常的正确解释(不是真的):

function loadRelease() {
    $scope.datas.releaseData = []; // LINE A
    angular.forEach($scope.datas.repositoryData, function(value, key) {
    GitHubService.getDevMasterReleaseDate(value.url).then(function(responseRepo) {
            var dataToOperate = [];
            var dataJson = {
                'repoName' : value.name,
                'masterArray' : [],
                'devArray' : [] 
            }

            angular.forEach(responseRepo.data, function(value, key) {
                if(value.target_commitish == 'master') {
                    dataJson.masterArray.push(value);
                } else {
                    dataJson.devArray.push(value);
                }
            });

            $scope.datas.releaseData.push(dataJson); // LINE B
        }, function(error) {

        });

    });
    console.log($scope.datas.releaseData); // LINE C
    console.log('length :: ' + $scope.datas.releaseData.length); //LINE D

}

在您的代码中,您正在做的是控制台记录在LINE A上初始化的空数组的长度(在上面的代码中标记)。长度是一个原始值,不会通过引用传递,而是通过值传递,因此对它的任何更新都不会反映在您的console.log中。但是,当您将实际数组记录在LINE C上时,它是通过引用console.log方法传递的,当GitHubService.getDevMasterReleaseDate的异步调用的承诺得到解决后,当传递的数组得到更新时,其值将在也要使用console.log方法,因为它是传递给引用而不是值。如果要获得预期的行为,则必须将控制台日志移至.then中传递的函数中。

答案 1 :(得分:0)

更新的解决方案:

您必须等到所有的诺言都解决后才能使用结果。您可以使用Promise.all

function loadRelease() {
    $scope.datas.releaseData = [];
    var promises = [];
    angular.forEach($scope.datas.repositoryData, function(value, key) {
        promises.push(GitHubService.getDevMasterReleaseDate(value.url).then(function(responseRepo) {
            var dataToOperate = [];
            var dataJson = {
                'repoName' : value.name,
                'masterArray' : [],
                'devArray' : [] 
            }

            angular.forEach(responseRepo.data, function(value, key) {
                if(value.target_commitish == 'master') {
                    dataJson.masterArray.push(value);
                } else {
                    dataJson.devArray.push(value);
                }
            });

            $scope.datas.releaseData.push(dataJson);
        }, function(error) {

        }));
    });
    Promise.all(promises).then(() => {
        console.log($scope.datas.releaseData);
        console.log('length :: ' + $scope.datas.releaseData.length);
    });
}

上一个答案:

您正在记录对API的异步调用之外的结果。

一旦从异步调用返回结果(当您注销对象/数组时),Chrome控制台实际上将更新记录的值,这就是第一个日志有结果的原因。但是,第二个是原始类型,因此它在记录时仍为真实值,即0。

如果要获得正确的输出,请将console.log移到.then函数中。

GitHubService.getDevMasterReleaseDate(value.url).then(function(responseRepo) {
    ...
    $scope.datas.releaseData.push(dataJson);
    console.log($scope.datas.releaseData);
    console.log('length :: ' + $scope.datas.releaseData.length);
}, function(error) {

});

答案 2 :(得分:0)

原因是“异步代码” $scope.datas.releaseData的值是在异步代码/ API / Ajax {GitHubService.getDevMasterReleaseDate} 中设置的。。 >

在最后一行的第二行为控制台编写的代码在执行时没有值,但是在chrome中,如果扩展了打印对象,它将显示该对象的最新值。为了清楚起见,请尝试用console.log(JSON.stringify($scope.datas.releaseData))

替换倒数第二行

但是控制台的最后一行是一个整数,它显示了执行时对象长度的正确值。

如果要在API之外获取对象的值

创建一个函数**(例如processReleaseData())**并在推送代码之后调用它。使用该函数,您将收到变量($scope.datas.releaseData)的值

function loadRelease() {
    $scope.datas.releaseData = [];
    angular.forEach($scope.datas.repositoryData, function(value, key) {
        GitHubService.getDevMasterReleaseDate(value.url)
            .then(function(responseRepo) {
                var dataToOperate = [];
                var dataJson = {
                    'repoName': value.name
                    , 'masterArray': []
                    , 'devArray': []
                }

                angular.forEach(responseRepo.data, function(value, key) {
                    if (value.target_commitish == 'master') {
                        dataJson.masterArray.push(value);
                    } else {
                        dataJson.devArray.push(value);
                    }
                });

                $scope.datas.releaseData.push(dataJson);
                processReleaseData($scope.datas.releaseData);
                //can call processReleaseData() directly also without 
                //passing arg
            }, function(error) {

            });
    });

    console.log($scope.datas.releaseData);
    console.log('length :: ' + $scope.datas.releaseData.length);
}

function processReleaseData(releaseData){
    //Do here whatever you want to do with releaseData;
    //You can also directly access the $scope.datas.releaseData here
}

答案 3 :(得分:0)

是的,以上两个答案都是正确的。您的代码是异步的。您正在登录控制台(并在从API提取$ scope.datas.releaseData之前使用它。) 如果您确实想在.then()之外访问$ scope.datas.releaseData,请传递一个函数作为回调,然后在.then()函数内部调用此函数。 从下面的代码中汲取灵感:

var logResponse = function(){

  console.log($scope.datas.releaseData);
  console.log('length :: ' + $scope.datas.releaseData.length);

}

loadRelease(logResponse); //pass variable containing your function

function loadRelease(myCallBack) {
  $scope.datas.releaseData = [];
  angular.forEach($scope.datas.repositoryData, function(value, key) {
    GitHubService.getDevMasterReleaseDate(value.url)
      .then(function(responseRepo) {
        var dataToOperate = [];
        var dataJson = {
          'repoName': value.name
          , 'masterArray': []
          , 'devArray': []
        }

        angular.forEach(responseRepo.data, function(value, key) {
          if (value.target_commitish == 'master') {
            dataJson.masterArray.push(value);
          } else {
            dataJson.devArray.push(value);
          }
        });

        $scope.datas.releaseData.push(dataJson);
        myCallBack(); //called here
      }, function(error) {

      });

  });
}

注意:以专业的方式使用Promises,因为如果使用过多的回调会导致 Callback Hells 。但是,如果您真的想了解承诺背后的逻辑,则可以使用或了解回调。

相关问题