7
votes

I am using angular2 version 2.4.7 and node 6.9.5

I want single angular application for front and admin. e.g. http://localhost:port for front side components, modules and routers. And http://localhost:port/admin for admin site components, modules and routers.

I have tried lots of solutions but I couldn't figure out proper solution.

Here is my sample code what I am currently using.

My folder structure

src
  app
     admin
         components
         models
         services
         admin.component.html
         admin.component.ts
         admin.module.ts
         admin.routing.ts
         main.ts
     site             
         components
         models
         services
         app.component.html
         app.component.ts
         app.module.ts
         app.routing.ts
         main.ts
  assets
  environments
  index.html
  main.ts
  polyfills.ts
  systemjs.config.js
  tsconfig.json
  (other angular2 required files)   

src/main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { AppModule } from './app/site/app.module';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);

src/app/admin/admin.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { FormsModule }    from '@angular/forms';
import { HttpModule } from '@angular/http';

// other required imports
import { MockBackend, MockConnection } from '@angular/http/testing';
import { BaseRequestOptions } from '@angular/http';

import { AdminComponent }  from './admin.component';
import { adminrouting }        from './admin.routing';

@NgModule({
    imports: [    
        CommonModule,
        adminrouting,
        HttpModule,
    ],
    declarations: [
        //declarations
    ],
    providers: [
        //providers
    ],
})

export class AdminModule { }

src/app/admin/admin.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'adminapp',
    templateUrl: 'admin.component.html'
})

export class AdminComponent {}

src/app/admin/admin.routing.ts

import { Routes, RouterModule } from '@angular/router';
//other impotrs

const appRoutes: Routes = [
    //my other routes
    // otherwise redirect to admin home
    { path: '**', redirectTo: '' }
];

export const adminrouting = RouterModule.forChild(appRoutes);

src/app/admin/admin.component.html and src/app/site/admin.component.html

currently both are same for admin and front. I want this different for both.

<!-- main app container -->
<div class="jumbotron">
    <div class="container">
        <div class="col-sm-8 col-sm-offset-2">                
            <router-outlet></router-outlet>
        </div>
    </div>
</div>

src/app/admin/main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AdminModule } from './admin.module';

platformBrowserDynamic().bootstrapModule(AdminModule);

src/app/site/app.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'app',
    templateUrl: 'app.component.html'
})

export class AppComponent { }

src/app/site/app.module.ts

// imports

@NgModule({
    imports: [
        BrowserModule,
        HttpModule,
        routing,
    ],
    declarations: [
        AppComponent,
        AdminComponent
        //other declarations
    ],
    providers: [
        //my providers
    ],
    bootstrap: [AppComponent, AdminComponent]
})

export class AppModule { }

src/app/site/app/routing.ts

import { Routes, RouterModule } from '@angular/router';

const appRoutes: Routes = [
    //other routes
    {
      path: 'admin',
      loadChildren: '../admin/admin.module#AdminModule',
    },
    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

export const routing = RouterModule.forRoot(appRoutes);

src/app/site/main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

src/index.html



<!DOCTYPE html>
<html>
<head>
    <base href="/" />
    <title>Angular 2 Example</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- bootstrap css -->

    <!-- application css -->

    <script src="systemjs.config.js"></script>
    <script>
        System.import('app').catch(function (err) { console.error(err); });
    </script>
</head>
<body>
    <app>Loading...</app>
    <adminapp></adminapp>
</body>
</html>

My this structure is working.

But my question is that is there any solution, I can use admin.html as index file for http://localhost:port/admin instead of index.html, right now this is same for both admin side and front side. Here in my index.html I have two tags for both side that is not good practice as I think. Both component will load in both url in this case.

<app></app>
<adminapp></adminapp>

Can any one please suggest me better approach for this. I don't want to make two different application for this.

Sorry for posting all code here, instead of using Plunker or anything else. But I don't have that practice.

I am totally newbie in angular2.

Thanks

2
I think I would prefer to have one index.html, and using two components. This simplifies your code tremendously. You only have to maintain the two different components, and the routes instead of managing what I would call two different projects. - John
Hi, can you pls provide this source code on github? Your question is not clear enough and its hard without showing the whole code and relationships - user2670818
@user2670818 thanks for taking interest, but right now I have solved my problem with John's suggestion. But I still curious for better solution to manage two different part/app, one for admin and one for front users. - herr

2 Answers

0
votes

You can use CanLoad guard for your admin route and check if user is allowed to access admin area. If not, she won't even load admin module...

{
  path: 'admin',
  canLoad: [UserGuard],
  loadChildren: '../admin/admin.module#AdminModule',
},
0
votes

You can try this, have 2 html files. And keep one root component, in that tag add one attribute to differentiate whether it's admin or other login (), in the root component constructor you can get the isAdmin attribute value using ElementRef (we can't use @Input to read the input value because browsers sometime doesn't consider the root tag as angular as it is not fully loaded ). Save this value in some common service used across the application, using this value we can create a canActivate service and attach this canActivate in routing module admin components. Check is this solve your issue.