在加载控制器之前验证路由前提条件

时间:2013-12-06 17:28:20

标签: dart angular-dart

我正在Angular中编写单页应用程序,特别是angular.dart,但我假设这个问题仍然适用于AngularJS。

以下列路线为例:

/ login - 预计没有人登录。如果某人经过身份验证但未注册,则重定向到“注册”路由,如果已注册,则重定向到“主页”路径。

/ register - 期望未完成注册过程的经过身份验证的用户。如果未经过身份验证,请重定向到登录。如果经过身份验证,请重定向到主页。

/ home - 期待经过身份验证和注册的用户。如果未经过身份验证,则重定向到“登录”路由,如果未注册,则重定向到“注册”路由。

我已经完成了相当多的搜索,但是在加载与特定路径关联的控制器之前无法找到内置或惯用的方法来确保满足某些先决条件,并在这些前提条件适当时重定向不满足。

非常感谢任何帮助!

4 个答案:

答案 0 :(得分:4)

Angular.Dart和Angular.JS路由框架非常/根本不同。 Angular.Dart使用第三方路由框架(https://github.com/dart-lang/route/tree/experimental_hierarchical),仅实现角度特定功能,如ng-view以及通过ViewFactory将路径绑定到模板的方法。

所以你的问题真的属于route_hierarchical包域。目前您可以否决用户尝试离开路线,但我猜您希望能够根据用户是否登录而否决用户输入路线的能力。不幸的是,这还没有得到支持,但是有计划的。

在此期间你可以尝试创建一个自定义的viewFactory包装器。

class RecipesRouteInitializer implements RouteInitializer {
   void init(Router router, ViewFactory view) {
     router
       ..addRoute(
          name: 'login',
          path: '/login',
          enter: authView(router, view('login.html'), NOT_AUTH))
       ..addRoute(
          name: 'register',
          path: '/register',
          enter: authView(router, view('register.html'), AUTH_NO_REG))
       ..addRoute(
          name: 'home',
          path: '/home',
          enter: authView(router, view('home.html'), AUTH_AND_REG));
   }

   authView(Router router, ngView, mode) {
     return (RouteEvent e) {
       if (mode == AUTH_AND_REG) {
         if (!authService.isAuth) {
           router.go('login', {});
           return;
         }
         if (!authService.isReg) {
           router.go('register', {});
           return;
         }
       } else if (mode == AUTH_NO_REG) {
         if (!authService.isAuth) {
           router.go('login', {});
           return;
         }
         if (authService.isReg) {
           router.go('home', {});
           return;
         }
       } else if (mode == NOT_AUTH) {
         if (authService.isAuth) {
           router.go('register', {});
           return;
         }
       }
       ngView(e);
     };
   }

}

DISCLAMER:这只是一个想法......可能完全不起作用。

答案 1 :(得分:3)

嗯,我在Dart做了一件事,它接近以前的一个解决方案,它没有真正起作用。重点是,在RouteEventHandler中,您需要调用视图的RouteEventHandler

      ..addRoute(
          name: 'userAdd',
          path: '/userAdd',
          enter: checkAuthentication(router,view,'view/addUser.html'))
      ..addRoute(
        name: 'login',
        path: '/login',
        enter: view('view/login.html'));
  }

  RouteEventHandler checkAuthentication(Router router,ViewFactory view, String location){
     return (RouteEvent e) {
      if(_authenticationService.isAuthenticated()){
        view(location)(e);
      }else{
        router.go("login",{});
      }
    };
  }

答案 2 :(得分:1)

注意:这仅适用于AngularJS,如果有人使用JS需要它,请留下它。

查看$routeProvider中的resolve媒体资源。您可以返回一个承诺,该承诺将决定是否接受路线变更。

来自文档:

  

如果这些依赖项中的任何一个是promise,路由器将在实例化控制器之前等待它们全部被解析或者一个被拒绝。如果成功解决了所有promise,则会注入已解析的promise的值并触发$ routeChangeSuccess事件。如果任何promise被拒绝,则触发$ routeChangeError事件。

还有关于它的视频和egghead.io上的路线生命周期here

答案 3 :(得分:0)

我知道以下解决方案不适用于Angular.Dart,但仍值得一提ui-router的解决方案:

https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-create-rules-to-prevent-access-to-a-state

app.config(function($stateProvider) {
  $stateProvider.state('privatePage', {
  data: {
    rule: function(user) {
    // ...
  }
});
});
app.run(function($rootScope, $state, $currentUser) {
$rootScope.$on('$stateChangeStart', function(e, to) {
if (!angular.isFunction(to.data.rule)) return;
var result = to.data.rule($currentUser);

if (result && result.to) {
  e.preventDefault();
  // Optionally set option.notify to false if you don't want 
  // to retrigger another $stateChangeStart event
  $state.go(result.to, result.params, {notify: false});
}
});
});