我将以这样一个事实为前提:我真的不知道这是否是实现我正在做的事情的最佳方式,而且我对更好的建议非常开放.
我有一个使用OAUTH2的用户帐户系统,它在我的数据库中查找用户信息并将其保存为变量$rootScope.userInfo.它驻留在一个附加到我的应用程序正文的控制器中;在这里,我认为最高级别的控制器会在其中存在之前加载,但显然不是.
如果我在mainCtrl有机会从我的数据库加载它之前加载一个试图访问这个$rootScope.userInfo对象的视图,它会抛出一个javascript错误和Angular中断.
作为参考,这里是模板的粗略概念:
<body ng-controller="mainCtrl"> <header>Content</header> <div class='main-view' ng-controller="userProfile"> <p>{{user.name}}</p> <p>{{user.email}}</p> </div> </body>
我在mainCtrl中加载$rootScope.userInfo,如下所示:
$http.get('/api/users/' + $cookies.id). success(function(data) { $rootScope.userInfo = data.user[0]; console.log("User info is:"); console.log($rootScope.userInfo); $scope.status = 'ready'; });
然后对于我的userProfile控件,我这样做:
function userProfile($scope,$cookies,$http,$routeParams,$rootScope){ if($scope.status == 'ready'){ $scope.user = $rootScope.userInfo; console.log("Double checking user info,here it is:"); console.log($rootScope.userInfo); } }
如果我来自应用程序中不调用$rootScope.userInfo的其他页面,则API有足够的时间查找它并且我的userProfile页面正常工作.但是,如果进行整页刷新,$rootScope.userInfo没有时间加载,我得到错误.
我怎样才能解决这个问题?
解决方法
您描述的问题是不建议使用$rootScope在控制器之间共享数据的原因之一:它在两个控制器之间创建手动“不可见”依赖关系,您必须在最终用户未完成时手动修复另一个控制器了.
建议的解决方案是将用户加载逻辑移动到服务中,例如userProfileService,您将其注入需要它的两个控制器中.然后它将被创建一次,并用于两个控制器.在这样的服务中,您可以在控制器请求时使用$http加载用户配置文件,并在下一个操作时从缓存中返回它.这样,依赖性从两个控制器到共享服务,而不是从一个控制器到另一个控制器.
我不是AngularJS文档的忠实粉丝,但这些可能会有所帮助:DI,Creating Services和Injecting Services.