Verifying route preconditions prior to loading controller

自作多情 提交于 2019-12-03 12:44:30
pavelgj

Angular.Dart and Angular.JS routing frameworks are very/fundamentally different. Angular.Dart is using a third party routing framework (https://github.com/dart-lang/route/tree/experimental_hierarchical) and only implements angular specific features like ng-view and ways to bind routes to templates via ViewFactory.

So your question really falls into the route_hierarchical package domain. Currently you can veto users attempt to navigate away from a route, but I guess what you want the ability to veto user entering a route depending on if the user is logged in or not. Unfortunately this is not yet supported, but is planned.

What you could try in the meantime is creating a custom viewFactory wrapper.

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: this is just an idea... might totally not work.

user3300744

Well, I made a thing in Dart which is close to one of the previous solutions which don't really work. The main point is that in the RouteEventHandler, you need to call the RouteEventHandler of the view.

      ..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",{});
      }
    };
  }

Note: this applies to AngularJS only, leaving this up in case someone using JS needs it.

Take a look at the resolve property in $routeProvider. You can return a promise which will determine whether the route change should be accepted or not.

From the docs:

If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired.

There's also a video about it and the route lifecycle on egghead.io here

I know that following solution is not applicable to Angular.Dart, but still is worth to mention solution for 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});
}
});
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!