gpt4 book ai didi

AngularJS 仅在父 Controller 完成异步调用时加载 Controller

转载 作者:行者123 更新时间:2023-12-04 14:59:21 31 4
gpt4 key购买 nike

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

架构如下。我有 :

1 - 管理整个站点显示的 MainCtrl(顶部菜单、模态等...)

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

2 - ng-view,每个页面都有一个 Controller ,每个页面都有一个由 $routeprovider 管理的自己的 Controller

主文件
.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 进行异步调用,以使 session 看起来像这样。
gapi.client.myapi.app.init().execute(function(resp){});

到目前为止,我所做的是将该代码包装在 MainCtrl 调用的 Service 函数中,然后在每个子 Controller 中监视 initDone 值,当异步调用完成时,该值会在 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;
}

});

示例控件
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 就会显示出来,从用户的 Angular 来看,这看起来不太好。

我尝试使用 $routeProvider 中的解析并从那里进行 API 调用,但随后我的 MainCtrl 无法正确获取 session 值。

我的解决方案是做一个:
   $routeProvider.when('/example', {
templateUrl : 'partials/example.html',
controller : 'ExampleCtrl',
access : accessLevels.PUBLIC,
resolve : MainCtrl.init
}

但是 MainCtrl 在 $routeProvider 中不可用

另一个想法是拦截 ng-view 调用,但我不确定在哪里执行此操作并同时访问 Service。

感谢您的任何想法/帮助

编辑

我试图在我的 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;
}]

});

如果我希望每个子 Controller 都调用 api,这会起作用。我想要的是让子 Controller 在 MainCtrl 准备好后使用它初始化的任何东西。基本上只在 MainCtrl 准备好时才加载 View 和关联的 Controller (包括异步调用

最佳答案

根据以下评论编辑

这个想法是用 ng-if 阻止 View ,直到 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>

旧答案:
你能把对谷歌的异步调用移到一个服务上,让那个服务返回一个 promise 吗?
     myApp.service('DataService', ['$rootScope', '$http', function ($rootScope, $http) {

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

在您的路由设置中,然后有一个解析,它将等待在对 Google 服务的调用返回后才加载 Controller
    when('/example', {templateUrl: 'partials/example.html', 
controller: 'ExampleCtrl',
resolve: {
'MyServiceData': function (DataService) {
return DataService.promise;
}
}}).

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

关于AngularJS 仅在父 Controller 完成异步调用时加载 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20440816/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com