2014-10-02 142 views
13

我是angularjs的新手。重新加载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:请原谅我发音不好。

回答

11

有没有必要重新加载您的控制器。角度足够聪明,可以在$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.isAuthenticated = AuthenticationService.isAuthenticated; 

然后在使用功能您的模板(不要忘记父母)

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

编辑:

虽然写普拉克告诉你我已经意识到指令的链接功能不叫一次更多的工作示例,从而在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

+0

谢谢,这就是我正在寻找的。 – BlackSalt 2014-10-03 08:13:05

+0

不幸的是,这个答案有点失败,每个人都在搜索如何重新加载控制器:(是的,在这种情况下不需要它,但还有其他用例(例如编写基础结构,可以重新初始化ui的位收到一个事件) – 2018-01-25 18:58:32

+1

@GeorgeMauer我不明白为什么在你的用例中需要一个控制器reolad。你能给更多的上下文吗?(也许最好打开一个新的SO问题作为一个无效的方法您的需求) – 2018-01-25 19:07:48

15

添加这段代码的用户通过验证后:

// 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) 
+0

感谢。为了刷新动态表,我使用了'$ scope。$ apply'。它在桌面上的Chrome浏览器上运行良好。但是,它并未在android webview中自动刷新。你使用'$ route'重新加载技术在android webview 4.4.2上工作 – nagu 2015-10-11 10:14:14