GVKun编程网logo

在Angular UI路由器中将$ state方法与$ stateChangeStart toState和fromState一起使用

14

在本文中,我们将带你了解在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一起使用

在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事件使您可以访问toStatefromState对象。这些状态对象将包含配置属性。

检查自定义模块属性的示例

$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之间的区别

$ 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混淆

$ 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造成无限循环

如何解决$ 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()之间的区别

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()之间的区别的相关知识,请在本站进行查询。

本文标签: