只有当父控制器完成异步调用AngularJS负载控制器控制器、负载、AngularJS

2023-09-13 03:15:33 作者:像一首歌

我建设有AngularJS和谷歌Cloudendpoint

I am building a website with AngularJS and Google Cloudendpoint

的体系结构如下。我有:

The architecture is as follow. I have :

1 - 管理整个网站显示一个MainCtrl(顶部菜单,情态动词等)

1 - a MainCtrl that manages the overall site display (top menus, modals, etc...)

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

2 - NG-视图为每个页面都有由$ routeprovider管理一个属于自己的控制器,控制器

2 - ng-view with a controller for each page that all have a their own controllers managed by the $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需要做一个异步调用到谷歌云端点,以获取会话看起来像这样。

The MainCtrl needs to do an async call to a Google Cloud Endpoint in order to get the session looking like this.

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

到目前为止,我所做的就是换行code由MainCtrl称为服务功能,然后做一个手表上initDone值获取的MainCtrl更新孩童控制器时,异步调用完成。

So far what I have done is wrap that code in a Service function called by the MainCtrl then do a watch in every children controller on an initDone value that gets updated in the MainCtrl when the async call is done.

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

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-观点等到MainCtrl做他的工作。

While this work I am not sure it is the right solution. What I would like would be to be able to keep the ng-view waiting until the MainCtrl has done his job.

由于做我做的方式意味着NG-视图获取显示的那么一旦到端点调用被更新看起来并不太好,从未来的用户。

Because doing the way I do it means that ng-view gets displayed then once the call to the endpoint gets updated which does not look too good from a user prospective.

我试图在$ routeProvider决心发挥并从那里做API调用,但后来我MainCtrl不能正常获取会话值。

I tried to play with the resolve in the $routeProvider and do the API call from there but then my MainCtrl does not get the session values properly.

什么是我的解决办法是做一个:

What would be my solution would be to do a :

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

但MainCtrl不可用在$ routeProvider

But MainCtrl is not available in the $routeProvider

另一个想法是拦截NG-视图呼叫,但我不知道在哪里可以做到这一点,在同一时间内获得服务。

Another idea would be to intercept the ng-view call but I am not sure where to do this and have access to Service at the same time.

感谢您的任何想法/帮助

Thanks for any idea/help

修改

我试图做我的main.js像这样

I tried to do something like this in my main.js

        $routeProvider.when('/example', {
            templateUrl : 'partials/example.html', 
            controller  : 'ExampleCtrl',
            access      : accessLevels.PUBLIC,

            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准备基本上只加载的意见和相关的控制器(包括异步调用

Which works if I want each children controller to call to the api. What I would like though is have the children controllers to use whatever the MainCtrl has initialized once it is ready. Basically only load the views and associated controller when MainCtrl is ready (async call included

推荐答案

的根据下面的评论编辑的

的想法是挡掉与视图纳克-如果直到该API调用返回:

The idea is to block off the view with an ng-if until the api call has returned:

// 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> 

旧的答案:你可以移动异步调用谷歌相关服务并有服务回报承诺

Old answer: Could you move the async call to Google to a service and have that service return a promise

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

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

在你的路由设置然后有一个决心,将等待调用谷歌的服务后,控制器自动返回唯一的负载

In your routing setup then have a resolve which will wait for the only load the controller after the call to the Google service has returned

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

编辑:这里有一个看看如何返回API调用 http://stackoverflow.com/a/16117041/一个承诺514463