代码之家  ›  专栏  ›  技术社区  ›  Sangram Badi

在angularjs中分析json数组不能正常工作

  •  2
  • Sangram Badi  · 技术社区  · 8 年前

    我有角度js应用程序。在这里,我尝试使用 angular.forEach . 它表现出奇怪的行为。

    当我试图控制它时,它显示的是数据,但当我试图控制长度时,它显示的是长度为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);
    
    }
    

    慰问:

    enter image description here

    4 回复  |  直到 8 年前
        1
  •  0
  •   Simon K    8 年前

    更新的解决方案:

    在尝试使用结果之前,必须等到所有的承诺都得到解决。你可以这样做 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 s在里面 .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
  •  1
  •   UtkarshPramodGupta    8 年前

    通过引用传递对象/数组,传递基元值 通过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
    
    }
    

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

        3
  •  0
  •   Anmol Deora    8 年前

    是的,以上两个答案都是正确的。你的代码是异步的。您正在控制台上登录(并在从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) {
    
          });
    
      });
    }
    

    注意 :以专业的方式使用承诺,因为回调如果使用过多,会导致 回叫地狱 . 但是,如果你真的想理解承诺背后的逻辑,你可以使用或理解回调。

        4
  •  0
  •   Ronit Mukherjee    8 年前

    原因是 “异步代码” 价值 $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
    }