0

I'm working on a web app where users have different access levels. Each access level has different sets of controllers/views.

I'm using ngRoute and ng-view. Each controller has its own JS file and it also contains the route mapping information for just that controller. Each controller looks like:

angular.module('MainApp', ['ngRoute'])

 .controller('ContollerX', function() {
 })

.config(function($routeProvider) {
  $routeProvider
  .when('/ControllerXURL', {
    templateUrl: 'ViewX.html',
    controller: 'ControllerX'
  });
});

(Not sure if it's the best practice)

I don't want to load all the controllers upfront. Is it possible to load just the controllers a user need based on a user's access level, which is determined after he/she logs in (user access level data returned from backend)? What would be the best approach?

I'm thinking to load the controller scripts dynamically, like inserting the script tag. Will it work? Does AngularJs have any built-in function for this?

1 Answer 1

0

There is a much easier way to achieve what you want using resolve property in route definition object. The resolve returns a promise and the route to the controller using resolve will be redirected only when this promise is resolved. You can use this to redirect to required view.

Say you have 2 views: AuthorizedUsers.html and UnauthorizedUsers.html and corresponding controllers AuthorizedUsersController and UnauthorizedUsersController. You can have your route definition for these views as below:

 angular
   .module('MainApp', ['ngRoute'])
   .controller('AuthorizedUsersController', function(auth) {
   })
   .controller('UnauthorizedUsersController', function() {
   })
   .config(function($routeProvider) {
     $routeProvider
       .when('/authorizedusers', {
         templateUrl: 'AuthorizedUsers.html',
         controller: 'AuthorizedUsersController',
         resolve: {
           auth: function ($q, $location) { 
             var defer = $q.defer();
             if (isAuthorized) {
               defer.resolve();
             } else {
               $location.path('/unauthorized');
               defer.reject();
             }
             return defer.promise;
           }
         }
       })
       .when('/unauthorizedusers', {
         templateUrl: 'UnauthorizedUsers.html',
         controller: 'UnauthorizedUsersController'
       });
   });
Sign up to request clarification or add additional context in comments.

10 Comments

Thanks for the info. It's good to know. But my question is actually how to load just the needed controller files "after" the user logs in.
Does that mean you want to actually defer loading the controller definitions until the user logs in? Angular doesn't provide a way to lazily load script resources and add them to the the application. Unless you've somehow created an enormous behemoth application you would probably be better off minifying and concatenating your entire code base into a single js file (or perhaps 2 or 3). You can also compile your html template into js and have it delivered as a single cached payload. Loading stuff on demand sounds good... until u have to wait for it load
Really? I thought it was better to load the scripts on demand since a user doesn't need all of them. Thanks for the info.
BTW, since Javascript is client-side, isn't the if (isAuthorized) easy to be hacked? The value of isAuthorized can be changed locally and thus the user can view authorized pages. Is it true?
You should not rely only on client side checks while exposing resources from server. The server api check should be independent of the client side check
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.