【问题标题】:Angularjs return data from the promise in controller's scopeAngularjs 从控制器范围内的承诺返回数据
【发布时间】:2014-10-22 01:39:30
【问题描述】:

亲爱的 AngularJS 专家,

如何在具有工厂返回承诺的控制器中设置 $scope.data。我所能做的就是使用工厂对象的方法范围内返回的数据,并且我不能将数据“加载”到控制器范围内现有的值中。如何将数据传递到控制器的范围内?

代码序列如下 这是工厂:

var features = {};        
        // the method returns a promise tot he controller needed to be delt with .then()
        features.getPromise = function(){
            //make a promise
            var promise = $http({method: 'GET', url: '../../LIBS/inc/getAllGeoFeatures.php'})
                .success(function(data, status, headers, config){
                    return data;
                })
                .error(function(data, status, headers, config){
                    $log.warn(data, status, headers, config);
                });
            return promise;
        };

这是控制器:

$scope.data = 'null';

        factGetFeat.getPromise().then(function(promise){

            $scope.data = promise;
            $log.info($scope.data);  //gets the object all right
           // here I can work with the data but I cannot share it with the controller
           // i.e. with the view
        });

        $log.info($scope.data); //$scope.data is still null and I need it loaded with the data

我需要一些建议,因为我觉得我无处可去

我什至尝试用方法的结果加载 $scope.data,但我只得到了承诺对象而不是数据:

对象{then:函数,catch:函数,finally:函数}

请指教。

附:我使用角度 1.2.x

非常感谢您的时间和耐心。

【问题讨论】:

    标签: javascript angularjs http promise


    【解决方案1】:

    应该是

    factGetFeat.getPromise().then(function(promise){
       $scope.data = promise;
       $log.info($scope.data);  //gets the object all right
    }).then(function(){
        // here you can see $scope.data updated with a new value
        $log.info($scope.data); 
    });
    

    作为替代:

    var promise = factGetFeat.getPromise().then(function(promise){
       $scope.data = promise;
       $log.info($scope.data);  //gets the object all right
    });
    
    promise.then(function(){
        // here you can see $scope.data updated with a new value
        $log.info($scope.data); 
    });
    

    .then 在第一个承诺解决时评估

    【讨论】:

      【解决方案2】:

      你做的几乎是对的。您只需要从您的服务中返回承诺。 如果我理解您的问题,当您在最后一页调用$log.info($scope.data) 时,您担心$scope.data 为空。这是完全正确的。 $scope.data 稍后会在 HTTP 调用成功完成时设置。 如果只需要在数据到达时进行任何操作,则必须包含success回调。

      这是它的样子:

      var app = angular.module('app',[]);
      
      app.factory('featuresService', ['$http', '$log', function($http, $log) {
      
          var getPromise = function() {
              //create the promise, this will be returned from this function
              var promise = $http({method: 'GET', url: '../../LIBS/inc/getAllGeoFeatures.php'});
      
              //on error do some logging here
              promise.error(function(data, status, headers, config) {
                  $log.warn(data, status, headers, config);
              });
      
              return promise;
          };  
      
          return {
              getPromise: getPromise;
          }
      
        }]);
      
      
      app.controller('testCtrl', 'featuresService', function($scope, featuresService) {
      
          //set initial values
          $scope.data = null;
          $scope.vectorAllLibs = null;
      
          var init = function() {
              featuresService.getPromise().then(function(data) {
                  $scope.data = data;
                  $scope.vectorAllLibs = convertVectorAllLibs(data);
              };
          };
      
          var convertVectorAllLibs = function(data) {
              return ol.source.GeoJSON({ projection: 'EPSG:3857', object: data });
          };
      
          $scope.processVectorAllLibs = function() {
              if (!$scope.vectorAllLibs) {
                  alert('sorry, no data yet!');
                  return;
              }
      
              //process here
          };
      
          init();
      
      });
      

      【讨论】:

      • 所以,只要 $scope.data 将在控制器中使用,数据就会被传递?!我说的对吗?所以,我不应该担心并开始添加将利用 $scope.data 中的数据的代码(何时且仅在使用 $scope.data 时交付?!我正确吗?
      • 不不不,不正确。数据将在准备好后交付,通过网络获取它们需要时间。这就是您承诺的 API 提供回调的原因,因此回调仅在数据到达时运行,而不是更早运行。如果您以 HTML 格式显示数据,则在数据准备好之前它将为空。如果您需要在代码中处理数据,那么您必须将代码放入回调中,以便代码在数据存在时运行。
      • 它开始逐渐变得有意义。嗯嗯……所以,控制器不可能知道数据何时到达。根据我的理解,从控制器的角度来看,我是否过早提出问题 $log.info($scope.data) ?问题是如何避免将利用数据的代码放在回调中?我需要在控制器中使用它才能绑定到视图...
      • 我问是因为稍后在控制器中我有以下序列: var vectorAllLibs = new ol.source.GeoJSON({ projection: 'EPSG:3857', object: $scope.data }); // 这里什么都没有发生,JSON 对象不存在
      • 你必须做的是让这个代码从成功回调中被调用。如果控制器在某处依赖vectorAllLibs 变量,则它必须计算该值也可以为空的选项。是的,你现在就是。控制器永远不知道数据何时到达,它只知道它会发生,来自成功回调的代码将被调用。
      猜你喜欢
      • 2015-05-30
      • 2014-06-24
      • 2016-07-27
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-08
      相关资源
      最近更新 更多