存储在 $rootScope 中的异步变量在其他控制器中不可用

Async variable stored in $rootScope not available in other controllers

我正在使用 Angular 1.x 作为我的堆栈,当我进行 API 调用并将响应存储在 $rootScope,在其他控制器的视图中是不可访问的。

我的控制器:

angularApp.controller('mainController', ['$scope', '$rootScope', '$http', function($scope, $rootScope, $http){

  var checkIfAuthenticated = function(){
    return $http.get('/api/isAuthenticated');
  };

  checkIfAuthenticated()
  .then(function(res) {
    if(res.status===200){
        console.log("Success");
        $rootScope.userLoggedIn = true;
    } 
  })
}]);

现在,在另一个控制器的视图中,我这样使用它:

<div ng-if="userLoggedIn" class="py-1 pl-1 pr-1">
  <span><b>Message Board</b></span>
  <div class="form-control" readonly id="lockTextbox">Show something</div>
</div>

问题是,API 调用 /api/isAuthenticated 确实提供了正确的响应(状态 200),但 ng-view 却出错了。

我确定这与 $rootScope.userLoggedIn 作为异步调用的响应有关(因为我在我的控制台中得到 Success)但我该如何解决它?

提前致谢!

编辑

发完问题后,我发现在mainController 看来,ng-if 逻辑也不行。非常奇怪的是,当我打开浏览器的调试控制台时,它开始工作了!我认为这只是一个异步问题,但我不知道如何解决。我如何告诉 view 变量正在路上?

好的,为了解决时间问题,我将彻底修改答案。这应该是一个 - 快速而肮脏但 - 有效的例子:

index.html

<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-app="plunker" ng-cloak>
    <div ng-controller="MainCtrl as $ctrl">
      <h1>Hello {{$ctrl.name}}</h1>
      <p>Start editing and see your changes reflected here!</p>
      <div ng-if="$ctrl.name === 'Angular.js'"><b>Message Board</b</div>
    </div>
  </body>
</html>

script.js

import angular from 'angular';

angular.module('plunker', []).controller('MainCtrl', function($scope, $http) {
  const self = this;
  self.name = 'Plunker';
  console.log('hello');

  function checkIfAuthenticated(){
    console.log('get');
   return $http.get('https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js');
  };

  checkIfAuthenticated().then(function(res) {
    if(res.status===200){
        console.log('Success');
        self.name = 'Angular.js'; // insert any logic here
    } else {
      console.log('Failed');
    }
  })
});

控制台

hello 
get 
Success 

对你有用吗?

工作示例

下面的演示显示了 $rootScope 变量在从延迟两秒的承诺设置后在两个控制器中可用。

angular.module("app",[])
.controller('mainController', function($scope, $rootScope, $timeout) {
  var checkIfAuthenticated = function(){
    return $timeout(function() {
        return { status: 200 };
    }, 2000);
  };
  checkIfAuthenticated()
  .then(function(res) {
    if(res.status===200){
        console.log("Success");
        $rootScope.userLoggedIn = true;
    } 
  })
})
.controller('otherController', function($scope) {
  console.log("other controller");
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
  <fieldset ng-controller="mainController">
     MAIN Controller userLoggedIn={{userLoggedIn}}<br>
     <div ng-if="userLoggedIn">
        Message Board - Show something
     </div>
  </fieldset>
  <fieldset ng-controller="otherController">
     OTHER Controller userLoggedIn={{userLoggedIn}}
     <div ng-if="userLoggedIn">
        Message Board - Show something
     </div>
  </fieldset>
</body>

我发现了问题。我将我的 Angular 从 1.6.4 更新到 1.7.9(以及 angular-sanitize 等所有模块)并且成功了。应该是我做的第一件事,但我完全错过了它