定义了变量的角度等待

时间:2016-02-14 00:11:35

标签: javascript angularjs

我有2个控制器和一个服务:

angular.module('objDescApp', ['ui.router', 'ui.bootstrap']);
angular.module('objDescApp').config(['$stateProvider', '$urlRouterProvider', '$httpProvider', function ($stateProvider, $urlRouterProvider, $httpProvider) {
                'use strict';
                $urlRouterProvider.otherwise('/');

                $stateProvider
                .state('object', {
                   url: '/{name}',
                   views: {
                        "body": {
                            controller: 'ObjectDetailCtrl',
                            template: '...'
                        }
                });


angular.module('objDescApp').controller('ObjectListCtrl', function ($scope, $state, ConfigService) {
  ConfigService.getConfig(function(){//get config from server
   $scope.object = ConfigService.fillConfigForObjList(); //use config
  }
}

angular.module('objDescApp').controller('ObjectDetailCtrl', ['$scope', '$stateParams', 'ConfigService',  function ($scope, $stateParams, ConfigService) {
   $scope.current_object = ConfigService.fillConfigForObjDetail(); //use config
}

angular.module('objDescApp').factory('ConfigService', function ($http, $rootScope) {
  var jsonConf;
  var confTemplate = {"sometemplate" : {}};

  function fillConfigForObjList (){
     ... //use jsonConf variable , and always wait for init because of called only inside callback function of getConfig();
  };
  function fillConfigForObjDetail(){
    ... //use jsonConf variable , but doesnt wait for jsonConf  initialization, so error var 'is undefined' here.So I need to add some waiting for 'jsonConf' initialization logic here

   };

   return {
              jsonConf: jsonConf,
              fillConfigForObjDetail: fillConfigForObjDetail,
              fillConfigForObjList: fillConfigForObjList,
              getConfig: function(callback){           
                            $http({
                              method: 'GET',
                              url: endPointUrl,
                              transformResponse: undefined
                            }).then(
                                function successCallback(response) {
                                    jsonConf = JSON.parse(response.data);
                                    $rootScope.getConfigError = false;
                                    callback();
                                },
                                function errorCallback(response) {
                                    if(response.status == "404"){
                                        jsonConf = confTemplate;
                                    }else{
                                        console.log("Get config error");
                                        jsonConf = confTemplate;
                                        $rootScope.getConfigError = true;
                                    }
                                    callback();
                                }
                            );
                        }
    }

因此,当我加载主路径'/'的页面时,一切正常,因为' ObjectListCtrl '控制器会触发 getConfig()功能在响应之后设置' jsonConf '变量,所以我可以在任何状态之间进行导航,所有工作正常,因为'jsonConf'已经设置;

但如果我重新加载具有'/ {name}'等起始路径状态的页面,那么' ObjectListCtrl '控制器trigers 'getConfig()' 对服务器的请求,但是以异步方式触发'ObjectDetailCtrl'控制器及其 $ scope.current_object = ConfigService.fillConfigForObjDetail()表达式,其中抛出{{ 1}} 那么有人可以告诉我如何通过getConfig()函数在'fillConfigForObjDetail()'函数内等待'jsonConf'变量init。

1 个答案:

答案 0 :(得分:0)

从承诺中保存承诺和

   var jsonConfPromise;

   function getConfig() {
       //save httpPromise           
       jsonConfPromise = $http({
                              method: 'GET',
                              url: endPointUrl,
                              transformResponse: undefined
                            }).then(
                                function successCallback(response) {
                                    jsonConf = JSON.parse(response.data);
                                    $rootScope.getConfigError = false;
                                    //return for chaining
                                    return jsonConf;
                                },
                                function errorCallback(response) {
                                    if(response.status == "404"){
                                        jsonConf = confTemplate;
                                    }else{
                                        console.log("Get config error");
                                        jsonConf = confTemplate;
                                        $rootScope.getConfigError = true;
                                    }
                                    //return for chaining
                                    return jsonConf;
                                }
                            );
       //return promise
       return jsonConfPromise;  
   };

您遇到问题的功能可以从承诺中链接

function fillConfigForObjDetail(){
    /*
    ... //use jsonConf variable , but doesnt wait for jsonConf
    initialization, so error var 'is undefined' here.
    So I need to add some waiting for 'jsonConf' initialization
    logic here
    */

    //chain from the promise
    jsonConfPromise.then(function (jsonConf) {
        //use resolved jsonConf
    });
};

同样在您的控制器中,而不是使用回传,来自返回的承诺。

angular.module('objDescApp').controller('ObjectListCtrl', function ($scope, $state, ConfigService) {
    var configPromise = ConfigService.getConfig();
    configPromise.then(function() {
         $scope.object = ConfigService.fillConfigForObjList();
    });
});

AngularJS框架使用承诺而不是回调

有关链接承诺的详细信息,请参阅AngularJS $q Service API Reference -- chaining promises

  

因为调用promise的then方法会返回一个新的派生promise,所以很容易创建一个promise链。可以创建任何长度的链,并且由于可以使用另一个承诺(将进一步推迟其解析)来解决承诺,因此可以在链中的任何点暂停/推迟承诺的解析。这使得实现强大的API成为可能。 1