无法将http结果保存到范围

时间:2016-11-01 16:38:48

标签: javascript angularjs json angularjs-scope http-get

我定义了一个json文件,我正在尝试加载我的一个控制器。我正在使用工厂来获取数据:

.factory('myService', function($http) {

  var all_data = [];

    return {
      getAllData: function(){
        return $http.get('js/data/all_data.json').then(function(data) {
          all_data  = data;
          return all_data ;
      });
        }
    }
})

稍后在我的控制器中,我在getAllData() - 函数中调用loadData()

.controller('QuizCtrl',['$scope','$state','$http','myService',function($scope,$state,$http,myService){

    // $scope.myData = []; <-- this makes the app freeze and not respond anymore
    $scope.loadData = function(){
      myService.getAllData().then(function(all_data){
          $scope.myData = all_data.data.all_data;
          alert($scope.myData);
      });
    }

    $scope.loadData();
    $scope.another_var = $scope.myData;

}])

正如您所看到的,我首先打电话给loadData()。在函数内部进行调试时(参见alert()),我可以清楚地看到如何加载json并将其应用于$scope.myData变量。

一旦我尝试将变量分配给另一个变量(参见$scope.another_var),myData就是'undefined'。

我尝试的是在$scope.myData调用之前定义$scope.loadData()(请参阅代码中的注释)。不幸的是,这个简单的变量声明使我的应用完全冻结。我还没有找到原因。此外,我不确定它是否与我的整体问题有关。

那么我错过了什么?为什么我无法将“http get”结果存储在我的控制器的$scope

编辑:所以在我的情况下,我需要在使用当前Controller之前存在数据。将所有在控制器中执行的代码放入承诺的.then链中是否合法?

3 个答案:

答案 0 :(得分:4)

这是因为您的HTTP请求是异步函数,而赋值$scope.another_var = $scope.myData;是同步的。

基本上发生的事情是,当加载QuizCtrl控制器时,它会在完成$scope.another_var = $scope.myData;的http请求之前完成语句getAllData()。你得到的是race condition

如果您想更改another_var的值,请在异步回调中移动它:

$scope.loadData = function(){
      myService.getAllData().then(function(all_data){
          $scope.myData = all_data.data.all_data;
          alert($scope.myData);

          // because now $scope.myData is available this assignment will work:
          $scope.another_var = $scope.myData;
      });
    }

$scope.loadData();

希望这有帮助。

答案 1 :(得分:1)

如果您需要根据范围内的值更新其他值,您可以观察更改的值并相应地更新。

这是你能做的。

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

app.controller("sampleController", ["$scope", "sampleService",
  function($scope, sampleService) {

    sampleService.sampleMethod(1).then(function(value) {
      $scope.value = value;
      $scope.$digest();
    }, function(error) {});

    $scope.$watch(function() {
      return $scope.value;
    }, function(newValue, oldValue) {
      //Default Value when the dependant value is not available
      newValue = newValue || 0;
      $scope.myNewValue = newValue * 10;
    });

  }
]);

app.service("sampleService", function() {
  this.sampleMethod = function(value) {
    var promise = new Promise(function(resolve, reject) {
      setTimeout(function() {
        value = value * 2;
        resolve(value);
      }, 1000);
    });
    return promise;
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="sampleApp">
  <div ng-controller="sampleController">
    <div>Value: {{value}}</div>
    <div>Cloned Value : {{myNewValue}}
    </div>
  </div>
</div>

答案 2 :(得分:0)

你错过了一个承诺$q

以此方法为例:

.factory('myService', function($http,$q) {
    var all_data = [];
    return {
        getAllData: function () {
            var d = $q.defer();
            $http.get('js/data/all_data.json')
                .success(function (response) {
                    d.resolve(response);
                });
            return d.promise;
        }
    }
})