我想不出一个合理的方法,感觉不像是黑客,来解决这个相当微不足道的问题。
我希望客人在访问网站索引时看到启动页面,并希望登录用户看到他们的个人资料,每个页面都有自己的模板和控制器。理想情况下,一个 url 会有两种状态,并且不知何故,我将能够根据登录状态自动更改活动状态。这两个视图都有自己的嵌套视图,因此不能使用 ng-include(我假设)。
我对 Angular 和 ui 路由器很陌生,我认为我可能忽略了一个简单的问题解决方案。
可以用命名视图和 ng-show 来完成吗?
我想不出一个合理的方法,感觉不像是黑客,来解决这个相当微不足道的问题。
我希望客人在访问网站索引时看到启动页面,并希望登录用户看到他们的个人资料,每个页面都有自己的模板和控制器。理想情况下,一个 url 会有两种状态,并且不知何故,我将能够根据登录状态自动更改活动状态。这两个视图都有自己的嵌套视图,因此不能使用 ng-include(我假设)。
我对 Angular 和 ui 路由器很陌生,我认为我可能忽略了一个简单的问题解决方案。
可以用命名视图和 ng-show 来完成吗?
如果您使用的是 UI 路由器,只需创建三个状态:根状态,带有'/'
URL,以及两个没有 URL 的直接后代状态。在onEnter
根状态中,您检测用户的状态并相应地转换到正确的子状态。这看起来为两个子状态保持相同的 URL,但允许您必须使用单独的配置来分隔状态。
templateUrl也可以是一个函数,因此您可以检查登录状态并返回不同的视图并在视图中定义控制器,而不是作为状态配置的一部分
我的解决方案:
angular.module('myApp')
.config(function ($stateProvider) {
$stateProvider
.state('main', {
url: '/',
controller: function (Auth, $state) {
if (someCondition) {
$state.go('state1');
} else {
$state.go('state2');
}
}
});
});
其中状态 1 和状态 2 在别处定义。
出于文档目的,我使用了:
$rootScope.$on('$stateChangeStart', function(event, toState) {
if ((toState.name !== 'login') && (!$localStorage.nickname)) {
event.preventDefault();
$state.go('login');
}
});
使用$routeChangeStart
对我不起作用。
它用于 ui-route 中的条件视图
$stateProvider.state('dashboard.home', {
url: '/dashboard',
controller: 'MainCtrl',
// templateUrl: $rootScope.active_admin_template,
templateProvider: ['$stateParams', '$templateRequest','$rootScope', function ($stateParams, templateRequest,$rootScope) {
var templateUrl ='';
if ($rootScope.current_user.role == 'MANAGER'){
templateUrl ='views/manager_portal/dashboard.html';
}else{
templateUrl ='views/dashboard/home.html';
}
return templateRequest(templateUrl);
}]
});
在任何地方(可能在某些高级控制器中),您应该能够将'$routeChangeStart'
事件绑定到$rootScope
然后进行检查:
$rootScope.$on('$routeChangeStart', function(next, current){
if(next != '/login' && !userLoggedIn){
$location.path( "/login" );
}
});
每次设置新路由时都会触发它,即使是在第一次访问页面时也是如此。
如果我理解这个问题;您想确保尚未登录的用户看不到需要登录的页面。正确吗?
我已经在控制器中使用这样的代码完成了此操作:
if(!'some condition that determines if user has access to a page'){
$location.path( "/login" );
}
我这样做的方法很简单。我为我们的 A/B 测试策略做了一个。这是要点:
resolve: {
swapTemplate: function(service) {
// all of this logic is in a service
if (inAbTest) {
this.self.templateUrl = '/new/template.html';
}
}
... other resolves
}
这会在模板下载之前被调用,因此您可以换出模板 url。
就我而言,如果两个状态可以共享同一个控制器的逻辑,那么条件模板是一个不错的选择。否则,创建单独的状态是一个不错的选择。