在本文中,我们将带你了解在AngularUI路由器中将$state方法与$stateChangeStarttoState和fromState一起使用在这篇文章中,同时我们还将给您一些技巧,以帮助您实现
在本文中,我们将带你了解在Angular UI路由器中将$ state方法与$ stateChangeStart toState和fromState一起使用在这篇文章中,同时我们还将给您一些技巧,以帮助您实现更有效的$ locationChangeStart,$ routeChangeStart和$ stateChangeStart之间的区别、$ locationChangeSuccess和$ stateChangeStart混淆、$ on('$ stateChangeStart')中的UI路由器$ state.go造成无限循环、Angular UI路由器中的$ state.transitionTo()和$ state.go()之间的区别。
本文目录一览:- 在Angular UI路由器中将$ state方法与$ stateChangeStart toState和fromState一起使用
- $ locationChangeStart,$ routeChangeStart和$ stateChangeStart之间的区别
- $ locationChangeSuccess和$ stateChangeStart混淆
- $ on('$ stateChangeStart')中的UI路由器$ state.go造成无限循环
- Angular UI路由器中的$ state.transitionTo()和$ state.go()之间的区别
在Angular UI路由器中将$ state方法与$ stateChangeStart toState和fromState一起使用
我正在为编写处理程序$stateChangeStart
:
var stateChangeStartHandler = function(e, toState, toParams, fromState, fromParams) { if (toState.includes(''internal'') && !$cookies.MySession) { e.preventDefault(); // Some login stuff. }};$rootScope.$on(''$stateChangeStart'', stateChangeStartHandler);
toState
没有include方法。我应该做些不同的事情,还是有办法做我想做的事情?
另外,当//一些登录内容包含时$state.go(...)
,我会遇到无限循环。是什么原因造成的?
这是一个更完整的示例,展示了我们最终要进行的工作:
angular.module(''test'', [''ui.router'', ''ngCookies'']).config([''$stateProvider'', ''$cookiesProvider'', function($stateProvider, $cookiesProvider) { $stateProvider .state(''public'', { abstract: true }) .state(''public.login'', { url: ''/login'' }) .state(''tool'', { abstract: true }) .state(''tool.suggestions'', { url: ''/suggestions'' });}]).run([''$state'', ''$cookies'', ''$rootScope'', function($state, $cookies, $rootScope) { $rootScope.$on(''$stateChangeStart'', function(e, toState, toParams, fromState, fromParams) { if (toState.name.indexOf(''tool'') > -1 && !$cookies.Session) { // If logged out and transitioning to a logged in page: e.preventDefault(); $state.go(''public.login''); } else if (toState.name.indexOf(''public'') > -1 && $cookies.Session) { // If logged in and transitioning to a logged out page: e.preventDefault(); $state.go(''tool.suggestions''); }; });});
我不喜欢indexOf
在中搜索特定状态toState
。感觉很幼稚。我不确定为什么toState
并且fromState
不能成为该$state
服务的实例,或者为什么该$state
服务不能在其方法中接受状态配置覆盖。
无限循环是由我们方面的错误引起的。我不喜欢这个,所以我还在寻找更好的答案。
答案1
小编典典建议1
当您$stateProvider.state
向该对象添加对象时,状态会被传递。因此,您可以添加其他属性,以便以后在需要时阅读。
路由配置示例
$stateProvider.state(''public'', { abstract: true, module: ''public''}).state(''public.login'', { url: ''/login'', module: ''public''}).state(''tool'', { abstract: true, module: ''private''}).state(''tool.suggestions'', { url: ''/suggestions'', module: ''private''});
该$stateChangeStart
事件使您可以访问toState
和fromState
对象。这些状态对象将包含配置属性。
检查自定义模块属性的示例
$rootScope.$on(''$stateChangeStart'', function(e, toState, toParams, fromState, fromParams) { if (toState.module === ''private'' && !$cookies.Session) { // If logged out and transitioning to a logged in page: e.preventDefault(); $state.go(''public.login''); } else if (toState.module === ''public'' && $cookies.Session) { // If logged in and transitioning to a logged out page: e.preventDefault(); $state.go(''tool.suggestions''); };});
我没有更改Cookie的逻辑,因为我认为这超出了您的问题。
建议2
您可以创建一个帮助程序,以使它更加模块化。
值publicStates
myApp.value(''publicStates'', function(){ return { module: ''public'', routes: [{ name: ''login'', config: { url: ''/login'' } }] };});
值privateStates
myApp.value(''privateStates'', function(){ return { module: ''private'', routes: [{ name: ''suggestions'', config: { url: ''/suggestions'' } }] };});
帮手
myApp.provider(''stateshelperConfig'', function () { this.config = { // These are the properties we need to set // $stateProvider: undefined process: function (stateConfigs){ var module = stateConfigs.module; $stateProvider = this.$stateProvider; $stateProvider.state(module, { abstract: true, module: module }); angular.forEach(stateConfigs, function (route){ route.config.module = module; $stateProvider.state(module + route.name, route.config); }); } }; this.$get = function () { return { config: this.config }; };});
现在,您可以使用助手将状态配置添加到您的状态配置中。
myApp.config([''$stateProvider'', ''$urlRouterProvider'', ''stateshelperConfigProvider'', ''publicStates'', ''privateStates'', function ($stateProvider, $urlRouterProvider, helper, publicStates, privateStates) { helper.config.$stateProvider = $stateProvider; helper.process(publicStates); helper.process(privateStates);}]);
这样,您可以抽象出重复的代码,并提出一个更具模块化的解决方案。
注意:以上代码未经测试
$ locationChangeStart,$ routeChangeStart和$ stateChangeStart之间的区别
我不知道什么是这三个不同,与其相应的$locationChangeSuccess
,$routeChangeSuccess
和$stateChangeSuccess
。
答案1
小编典典$ locationChangeStart:
这使用$location
提供程序并在URL更改时广播。位置更多是指特定URL的路径。它更像普通的JavaScript,您可以更改到应用程序中的任何路径,并且在应用程序中将其定义为路由还是状态都没有关系。
$ routeChangeStart:
这使用$route
提供程序,并且与broadcasts
更改路由时使用的提供程序相同(与一起使用的默认Angular路由器ngRoute
)。这用于在控制器和视图之间建立链接。
$ stateChangeStart: 它在您的状态更改时发生,并且在过渡开始时广播。ui-
router使用它提供了routeprovider的不同(更高级)实现。使用状态,您可以映射和访问有关不同状态的不同信息,并且可以通过轻松在状态之间传递信息$stateParams
。
它们非常相似,实际上它们共享相同的名称,但是主要区别取决于应用程序使用的路由。如果您使用角度路由器,则坚持使用路由,但是,如果您使用ui-
router,则坚持使用状态。这是我可以给您的实用建议。
$ locationChangeSuccess和$ stateChangeStart混淆
我正在尝试使用AngularUI路由器进行一些身份验证。$urlRouter.sync()
看起来正是我所需要的。但是,仅当我拦截时可用$locationChangeSuccess
。但是当我这样做时,它$state.current.name
是空的,而我希望它是当前状态。
到目前为止,这是我的代码:
$rootScope.$on(''$locationChangeSuccess'', function(event, next, nextParams) { event.preventDefault(); if ($state.current.name === ''login'') { return userService.isAuthenticated().then(function(response) { var authenticated; authenticated = response.authenticated; return alert(authenticated); }); }});
关于我在做什么错的任何指示?
答案1
小编典典我建议走更多的UI-Router
路。我们应该使用适当提供的$rootScope.$on(''$stateChangeStart''
事件$state.current
。这是一个有效的例子
让我们观察一下简单的 (但不是幼稚的) 解决方案,它可以在以后扩展到任何程度。
首先,让我们定义用户服务,如下所示:
.factory(''userService'', function ($timeout, $q) { var user = undefined; return { // async way how to load user from Server API getAuthObject: function () { var deferred = $q.defer(); // later we can use this quick way - // - once user is already loaded if (user) { return $q.when(user); } // server fake call, in action would be $http $timeout(function () { // server returned UN authenticated user user = {isAuthenticated: false }; // here resolved after 500ms deferred.resolve(user) }, 500) return deferred.promise; }, // sync, quick way how to check IS authenticated... isAuthenticated: function () { return user !== undefined && user.isAuthenticated; } }; })
因此,我们使用async _(此处为$timeout
)_从user
服务器加载对象。在我们的示例中,它将具有属性{isAuthenticated: false }
,该属性将用于检查是否已通过身份验证。
还有一个sync方法isAuthenticated()
,直到加载并允许用户-始终返回false
。
那将是我们对''$stateChangeStart''
事件的听众:
.run([''$rootScope'', ''$state'', ''userService'', function ($rootScope, $state, userService) { $rootScope.$on(''$stateChangeStart'', function (event, toState, toParams , fromState, fromParams) { // if already authenticated... var isAuthenticated = userService.isAuthenticated(); // any public action is allowed var isPublicAction = angular.isObject(toState.data) && toState.data.isPublic === true; if (isPublicAction || isAuthenticated) { return; } // stop state change event.preventDefault(); // async load user userService .getAuthObject() .then(function (user) { var isAuthenticated = user.isAuthenticated === true; if (isAuthenticated) { // let''s continue, use is allowed $state.go(toState, toParams) return; } // log on / sign in... $state.go("login"); }) ...
我们首先要检查的是用户是否已经加载并通过身份验证 (var isAuthenticated =...
)。接下来,我们将为任何公共方法赋予绿色。这是通过data{}
状态对象定义的属性完成的(请参阅将自定义数据附加到状态对象)
就是这样。在下面的代码段中定义状态的情况下,我们可以体验到:
- 的
''public''
,''home''
允许任何人 ''private''
,''private''
如果出现以下情况,将重定向到登录名isAuthenticated === false
在
''login''
这个例子提供了快捷的方法如何打开/关闭isAuthenticated// States
$stateProvider
// public
.state(‘home’, {
url: “/home”,
templateUrl: ‘tpl.html’,
data: { isPublic: true },
})
.state(‘public’, {
url: “/public”,
templateUrl: ‘tpl.html’,
data: { isPublic: true },
})
// private
.state(‘private’, {
url: “/private”,
templateUrl: ‘tpl.html’,
})
.state(‘private2’, {
url: “/private2”,
templateUrl: ‘tpl.html’,
})// login
.state(‘login’, {
url: “/login”,
templateUrl: ‘tpl.html’,
data: { isPublic: true },
controller: ‘loginCtrl’,
})
检查所有这里
$ on('$ stateChangeStart')中的UI路由器$ state.go造成无限循环
如何解决$ on(''$ stateChangeStart'')中的UI路由器$ state.go造成无限循环?
一般来说,我 *
if (toState.name === ''login'' ){
// doe she/he try to go to login? - let him/her go
return;
}
if(Auth.isLoggedIn()){
// is logged in? - can go anyhwere
return;
}
// else
$state.go(''login'')
这是简化的逻辑,但表明,仅在需要时才应更改为执行。还有一些其他示例,其中包含更详细的实现方式和功能:
正如评论中所提供的,有一个plunker,我在这里像这样更改
...
// three new lines
if (toState.name === ''specialRoute''){
return;
}
if (fromState.name==''route1''){
event.preventDefault();
$state.go(''specialRoute'')
}
而且这 循环了。请在这里检查
解决方法
我正在尝试将登录信息引入用户浏览应用程序的方式。
如果用户满足特定要求,我假装将用户重定向到该页面,直到他导航到登录页面之前
防止事件从$ stateChangeStart停止,阻止状态更改,如预期的那样,但是当我运行$
state.go(’into_somewhere’)时,我进入无限循环
我的角度版本是1.3.1,而ui-router是最新的
.factory(''RouteHistory'',function ($rootScope,$log,$state,Auth,$urlRouter,$timeout) {
// after the user enter a page
var currentState = '''';
// when the user is trying to access a page that he has not permissions
// or that requires the user to be logged in
var pendingState = '''';
var isMenuTogglerVisible = false;
var skipFromStateVal = true;
$rootScope.$on(''$stateChangeStart'',function(event,toState,toParams,fromState,fromParams){
event.preventDefault();
if (toState.name == ''login'' && fromState.name != ''login''){
$log.log(''Ui-router: changing to login'');
// $urlRouter.sync();
$state.go(''login'')
//pendingState = fromState;
//$log.log(''Peding state updated to:'' + pendingState.name );
//$urlRouter.sync();
}
if (fromState.name == ''login'' && Auth.isLoggedIn()) {
$log.log(''Ui-router: going from login'');
//$state.go(fromState.name);
$timeout(function(){
// $state.go(''home'',null,{/*reload: true,location: ''replace''*/});
$state.go(''browse-machine'');
//$urlRouter.sync();
},2000)
}
$log.log({
''toState'': toState,''toParams'': toParams,''fromState'': fromState,''fromParams'': fromParams
})
})
return {
};
});
Angular UI路由器中的$ state.transitionTo()和$ state.go()之间的区别
在AngularJS中,我看到有时使用$state.transitionTo()
有时使用$state.go()
。谁能告诉我它们的区别以及何时应使用另一种?
今天的关于在Angular UI路由器中将$ state方法与$ stateChangeStart toState和fromState一起使用的分享已经结束,谢谢您的关注,如果想了解更多关于$ locationChangeStart,$ routeChangeStart和$ stateChangeStart之间的区别、$ locationChangeSuccess和$ stateChangeStart混淆、$ on('$ stateChangeStart')中的UI路由器$ state.go造成无限循环、Angular UI路由器中的$ state.transitionTo()和$ state.go()之间的区别的相关知识,请在本站进行查询。
本文标签: