user3718908x100
user3718908x100

Reputation: 8509

Sub Domain Routing in AngularJS

Hello i am new to AngularJS, i have done my research and i know redirecting to a sub domain will cause the page to refresh. What i want to know is how to check what the sub domain is when a link is clicked and load the right view and controller.

I use wildcard sub domains but i basically have three of them right now:

  1. administrator.example.com
  2. manager.example.com
  3. employee.example.com

Each sub-domain should redirect you to their respective dashboard view and controllers.

The main url however example.com shall direct you to the website itself.

I have set-up my states like this:

app

app.administrator
app.administrator.dashboard

app.manager
app.manager.dashboard

app.employee
app.employee.dashboard

Upvotes: 1

Views: 5352

Answers (2)

Mohan Singh
Mohan Singh

Reputation: 883

Here i am going to give you standard solution to your problem. You should create a separate application for each subdomain. I have created a sample application to demonstrate the flow.

Index.html

 <!DOCTYPE html>
  <html ng-app="app">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script data-require="[email protected]" data-semver="2.0.0" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <link data-require="[email protected]" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <script data-require="[email protected]" data-semver="3.3.5" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script>
      document.write('<base href="' + document.location + '" />');
    </script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>

    <script src="app.js"></script>
    <script src="app.manager.js"></script>
  </head>

  <body>
    <load-application></load-application>
  </body>

  </html>

app.js

  /**
   * @name app
   * 
   * Lets create angular application module
   * if second parameter is passed with enpty array [] or with dependecies , is    * called angular module setter
   * 
   * angular.module('app', []); Setter
   * angular.module('app'); Getter
   */
  angular
    .module('app', ['appLoader']);

  /**
   * app.administrator application for aministrator subdomain
   */
  angular
    .module('app.administrator', ['ui.router']);

  /**
   * app.employee application for employee subdomain
   */
  angular
    .module('app.employee', ['ui.router']);


  /**
   * Lets create a application loader
   * This component is going to load sub domain specific application
   */
  angular
    .module('appLoader', ['app.administrator', 'app.manager', 'app.employee'])
    .directive("loadApplication", ['$location', function($location) {
      function getDomain() {
        console.log($location.host());
        //get domain name here
        return 'manager';
      }
      return {
        restrict: 'E',
        controller: function($scope, $element, $attrs, $transclude) {},
        template: function() {
          var domainName = getDomain(),
            templateName = '';
          switch (domainName) {
            case 'manager':
              templateName = '<app-manager></app-manager>';
              break;
            case 'employee':
              templateName = '<app-employee></app-employee>';
              break;
            case 'administrator':
              templateName = '<app-administrator></app-administrator>';
              break;
          }
          return templateName;
        },
        link: function($scope, element, attrs) {
          console.info('loader application');
        }
      };

    }]);


  angular
    .module('app.administrator')
    .directive("appAdministrator", ['$location', function($location) {

      return {
        restrict: 'E',
        template: '<h2>{{applicationName}}</h2>',
        link: function($scope, element, attrs) {
          $scope.applicationName = 'Application Administrator';
        }
      };

    }]);

  angular
    .module('app.employee')
    .directive("appEmployee", ['$location', function($location) {

      return {
        restrict: 'E',
        template: '<h2>{{applicationName}}</h2>',
        link: function($scope, element, attrs) {
          $scope.applicationName = 'Application Employee';
        }
      };

    }]);

app.manager.js

 angular
    .module('app.manager', ['ui.router']);

  angular
    .module('app.manager')
    .config(function($stateProvider, $urlRouterProvider) {
      $urlRouterProvider.otherwise("/");
      $stateProvider
        .state('index', {
          url: '/',
          template: '<ul><li><a ng-href="#" ui-sref="demopage1">Demo page 1</a></li><li><a ng-href="#" ui-sref="demopage2">Demo page 2</a></li></ul>'
        })
        .state('demopage1', {
          url: '/demopage1',
          template: '<ul><li><a ng-href="#" ui-sref="demopage1">Demo page 1</a></li></ul>'
        })
        .state('demopage2', {
          url: '/demopage2',
          template: '<ul><li><a ng-href="#" ui-sref="demopage1">Demo page 1</a></li></ul>'
        })
    });

  angular
    .module('app.manager')
    .directive("appManager", ['$location', function($location) {

      return {
        restrict: 'E',
        template: '<h2>{{applicationName}}</h2><div ui-view></div>',
        link: function($scope, element, attrs) {
          $scope.applicationName = 'Application Manager';
        }
      };

    }]);

Working plunker is here

I have created 3 applications for three domains , each application works independently. I have implemented the UI routes in app.manager application. You can implement the same in rest applications.

Lets me know if you have any concern ?

Upvotes: 2

TonyW
TonyW

Reputation: 18895

If you haven't started using the routing module called ui.router in your angular-based app, I suggest you read it here. I believe it is much more powerful than the ngRoute module native in Angular 1.x.

From my understanding your subdomain, I think you can arrange them as nested domains (or to be more precise, states) under 'app'. If the root url of your 'app' is something like '/main/', then the subdomains will inherit that root url and take the form such as '/main/administrator' and '/main/administrator/dashboard'

Each state (including nested states) can have its own controller, in which you can use the $state service in ui.router to get the state name (or subdomain name as you said) by calling: $state.$current.name

I hope this helps

As an example from my previous work. Here the main app has the url '/webapp', and the rest of the states are nested states that have their url started with '/webapp', e.g. for the state 'home.blogs', its url is '/webapp/blogs'. If it's still confusing, I suggest you spend some time reading the documentation on ui.router at Github.

angular
  .module('blogFrontendApp', [
    'ui.router'
  ])

config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/webapp/blogs');

    $stateProvider.state('home', {
     // abstract: true,
      url: '/webapp',
      views: {
        '' : {
          templateUrl: 'views/main.html'
        },
        'rightPanel@home' : {
          templateUrl: 'views/rightPanel.html'
        },
        'mainContent@home' : {
          templateUrl: 'views/mainContent.html'
        }
      }
    })

      .state('home.blogs', {
        //to be shown in mainContent@home
        url: '/blogs',
        templateUrl: 'views/home_blogs.html'
      })

      .state('home.singleBlog', {
        url: '/blog/:blogId/:blogTitle',
        templateUrl: 'views/single_blog.html',
        controller: 'blogArticleController as currentBlogView',
        resolve: {
          BlogService : 'BlogService',
          blogObj : function(BlogService, $stateParams) {
            return BlogService.getBlogById($stateParams.blogId);
          }
        }
      })

      .state('home.blogListInCategory', {
        url: '/blogs/category/:categoryId',
        templateUrl: 'views/blog_list_in_category.html',
        controller: 'blogListController as blogListView'
      })

      .state('home.publishBlog', {
        url: '/blogs/:categoryId/new',
        templateUrl: 'views/publish_blog.html',
        controller: 'blogListController as writeBlogView'
      })
}

Upvotes: 0

Related Questions