【问题标题】:Can't save http result to scope无法将 http 结果保存到范围
【发布时间】:2016-11-01 16:38:47
【问题描述】:

我定义了一个 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 ;
      });
        }
    }
})

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

.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 是“未定义”。

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

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

编辑:所以在我的例子中,我需要数据在当前控制器被使用之前就已经存在。将控制器中执行的所有代码放入promise的.then-chain 是否是一个合法的选择?

【问题讨论】:

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


    【解决方案1】:

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

    基本上,当你的QuizCtrl 控制器被加载时,它会在完成getAllData() 的http 请求之前完成语句$scope.another_var = $scope.myData;。你得到的是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();
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      如果您需要根据范围内的值更新不同的值,您可以观察值的变化并相应地更新。

      这是你可以做的。

      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>

      【讨论】:

        【解决方案3】:

        你错过了一个承诺$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;
                }
            }
        })
        

        【讨论】:

        • 不幸的是,这并没有解决问题@Marc Rassmussen
        • @Käsebrot 您能否发布一个小提琴或类似的东西,然后我很乐意查看并使其正常工作。我 100% 确定它与承诺有关
        猜你喜欢
        • 2019-02-19
        • 2015-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-21
        • 1970-01-01
        • 2021-09-24
        • 2013-08-25
        相关资源
        最近更新 更多