【问题标题】:Reload AngularJS Controller重新加载 AngularJS 控制器
【发布时间】:2014-10-02 22:27:24
【问题描述】:

我是 angularjs 的新手。

我的问题是我有一个用于处理登录和注销的用户控制器。我还有另一个控制器来为我的站点加载标题菜单。

如果用户登录到站点,我的 isAuthenticated 变量设置为 true。如果变量设置为true,则标题应该更改但是,所以我认为必须重新加载控制器才能更改标题视图。

这里是我的 HeaderController 的代码:

myapp.controller('HeaderController', ['$scope', '$location', '$window', 'AuthenticationService',  
    function HeaderController($scope, $location, $window, AuthenticationService) {
        $scope.isAuthenticated = AuthenticationService.isAuthenticated;

        if (AuthenticationService.isAuthenticated) {
            $scope.user.vorname = $window.sessionStorage.user.vorname;
        }
    }
]);

这是我的 HeaderDirective 的代码:

myapp.directive('appHeader', function() {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      if (attrs.isauthenticated == 'false') {
        scope.headerUrl = 'views/header/index.html';
      } else {
        scope.headerUrl = 'views/header/isAuthenticated.html';
      }
    },
    template: '<div ng-include="headerUrl"></div>'
  }
});

我的 index.html:

<div ng-controller="HeaderController">
  <app-header isauthenticated="{{isAuthenticated}}"></app-header>
</div>

如果用户登录页面,如何重新加载控制器?

PS:请原谅我发音不好。

【问题讨论】:

    标签: javascript angularjs controller


    【解决方案1】:

    用户认证后添加这段代码:

    // To refresh the page
    $timeout(function () {
        // 0 ms delay to reload the page.
        $route.reload();
    }, 0);
    

    不要忘记在您的控制器中包含$timeout$route

    myapp.controller('HeaderController', ['$scope', '$location', '$window', 'AuthenticationService', '$timeout', '$route',
    function HeaderController($scope, $location, $window, AuthenticationService, $timeout, $route)
    

    【讨论】:

    • 谢谢。为了刷新动态表,我使用了$scope.$apply。它在桌面上的 Chrome 浏览器上运行良好。但是,它没有在 android webview 上自动刷新。您使用 $route 重新加载的技术适用于 android webview 4.4.2
    【解决方案2】:

    无需重新加载控制器。 Angular 足够聪明,可以在 $scope.isAuthenticated 状态更改时更改模板。

    我在您的代码中看到的一个问题是,一旦定义了$scope.isAuthenticated,它就不再改变。我想您在用户登录时设置了 AuthenticationService.isAuthenticated = true,但该更改并未传播到 $scope.isAuthenticated 属性,因为在 JavaScript 中,标量值是按值而不是按引用复制的。

    有很多方法,例如将AuthenticationService.isAuthenticated属性从布尔值更改为函数:

    angular.module('auth', [])
    .factory('AuthenticationService', function () {
        // private state
        var isAuthenticated = false;
    
        // getter and setter
        var auth = function (state) {
            if (typeof state !== 'undefined') { isAuthenticated = state; }
            return isAuthenticated;
        };
    
        // expose getter-setter
        return { isAuthenticated: auth };
    });
    

    然后将该函数分配给$scope:

    $scope.isAuthenticated = AuthenticationService.isAuthenticated;
    

    然后在模板中使用该函数(不要忘记括号)

    <app-header isauthenticated="{{ isAuthenticated() }}"></app-header>
    

    编辑:

    在编写一个 plunk 向您展示一个工作示例时,我意识到 该指令的链接函数不会被多次调用,因此正如 this stackoverflow thread 中所公开的那样,我只是将指令修改为观察isauthenticated 属性的变化:

    angular.module('directives', [])
    .directive('appHeader', function() {
      var bool = {
        'true': true,
        'false': false
      };
    
      return {
        restrict: 'E',
        link: function (scope, element, attrs) {
          attrs.$observe('isauthenticated', function (newValue, oldValue) {
            if (bool[newValue]) { scope.headerUrl = 'authenticated.html'; }
            else { scope.headerUrl = 'not-authenticated.html'; }
          });
        },
        template: '<div ng-include="headerUrl"></div>'
      }
    });
    

    还有here is the working example

    【讨论】:

    • 谢谢,这就是我要搜索的内容。
    • 不幸的是,对于寻找如何实际重新加载控制器的每个人来说,这个答案有点失败:(。是的,在这种情况下不需要它,但是还有其他用例(例如编写可以重新加载的基础架构) -在收到事件后初始化 ui 的位)
    • @GeorgeMauer 我不明白为什么在您的用例中也不需要控制器重新加载。你能提供更多的上下文吗? (也许最好打开一个新的 SO 问题链接到这个问题,作为满足您需求的无效方法)
    猜你喜欢
    • 1970-01-01
    • 2014-02-03
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    相关资源
    最近更新 更多