微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

AngularJS仅在父控制器完成异步调用时加载控制器

我正在使用AngularJS和Google Cloudendpoint构建一个网站

架构如下.我有

1 – 管理整个站点显示的MainCtrl(顶级菜单,模态等…)

<body ng-controller="MainCtrl" ng-cloak main-directive>
    ...
    <div ng-view></div>
    ...
</body>

2-ng-view,每个页面都有一个控制器,所有控制器都有一个由$routeprovider管理的控制器

main.js

.config([
    '$routeProvider','$locationProvider','$httpProvider',function($routeProvider,$locationProvider,$httpProvider) {

                    ...
        $routeProvider.when('/example',{
            templateUrl : 'partials/example.html',controller  : 'ExampleCtrl',access      : accessLevels.PUBLIC
                    }
                    ...
        $routeProvider.otherwise({redirectTo: '/'});
    }

MainCtrl需要对Google Cloud Endpoint执行异步调用,以使会话看起来像这样.

gapi.client.myapi.app.init().execute(function(resp){});

到目前为止,我所做的是将该代码包装在由MainCtrl调用的Service函数中,然后在initDone值上的每个子控制器中执行监视,当异步调用完成时,该值在MainCtrl中更新.

MainCtrl

SessionService.init().then(function(data){
    $scope.initDone = SessionService.getinitDone();
});

服务

angular.module('myapp.services').service('SessionService',function ($http,$q,$rootScope) {

this.initDone = false
this.session = {}

this.init = function(){
    var s = this; 
    var deferred = $q.defer();
    gapi.client.myapi.app.init().execute(function(resp){
        deferred.resolve(resp);
        s.initDone = true;
    });
    return deferred.promise;
}

this.getinitDone = function(){
    return this.initDone;
}

});

ExampleCtrl

angular.module('myapp.controllers').controller('ExampleCtrl',function MainCtrl($scope,$timeout,$log,$location,SessionService) {

$scope.$watch('initDone',function(newVal,oldVal){
    $scope.testValue = SessionService.getinitDone()
})

});

虽然这项工作我不确定这是正确的解决方案.我想要的是能够让ng-view等待直到MainCtrl完成他的工作.

因为按照我这样做的方式意味着一旦对端点的调用得到更新,就会显示ng-view,这对用户的预期来说看起来不太好.

我尝试在$routeProvider中使用解析并从那里执行API调用,但是然后我的MainCtrl没有正确获取会话值.

我的解决方案是做一个

$routeProvider.when('/example',{
templateUrl : 'partials/example.html',access      : accessLevels.PUBLIC,resolve     : MainCtrl.init
}

但$routeProvider中没有MainCtrl

一个想法是拦截ng-view调用,但我不知道在哪里这样做并且可以同时访问服务.

感谢您的任何想法/帮助

编辑

我试着在main.js中做这样的事情

$routeProvider.when('/example',resolve: {
                sessionData: ["$q","SessionService",function($q,SessionService) {
                    //console.log(SessionService.gettest())

                    var deferred = $q.defer();
                    gapi.client.myapi.app.init().execute(function(resp){
                        deferred.resolve(resp);
                    });
                    return deferred.promise;
                }]

        });

如果我希望每个子控制器调用api,哪个有效.我想要的是让子控制器使用MainCtrl准备好后初始化的任何东西.基本上只在MainCtrl准备就绪时加载视图和相关的控制器(包括异步调用

根据以下评论进行编辑

这个想法是用ng-if阻止视图直到api调用返回

// Session service
 this.init = function(){
      if (!this.initDone){
          var s = this;
          var deferred = $q.defer();
          gapi.client.myapi.app.init().execute(function(resp){
              deferred.resolve(resp);
              s.initDone = true;
          });
          return deferred.promise;
      }
 }




// MainController.js :
 $scope.initDone = false;
 SessionService.init().then(function(
     $scope.initDone = SessionService.getinitDone();
  });


// index.html: 
<div ng-if="initDone"> 
    <div id="view" ng-view> </div>
</div>

老答案:
您是否可以将异步调用移至Google服务并让该服务返回承诺

myApp.service('DataService',['$rootScope','$http',function ($rootScope,$http) {

     var promise = $http.get("http://google.com/theservice").success(function (data) {
             ......
      });
      this.promise = promise

在您的路由设置中,然后有一个解决方案,等待在返回Google服务的调用后唯一加载控制器

when('/example',{templateUrl: 'partials/example.html',controller: 'ExampleCtrl',resolve: {
            'MyServiceData': function (DataService) {
                return DataService.promise;
            }
        }}).

编辑:看看这里如何返回api调用https://stackoverflow.com/a/16117041/514463的承诺

原文地址:https://www.jb51.cc/angularjs/240557.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐