<!DOCTYPE html>
<html>

  <head>
    <base href="." />
    <title>angular2 playground</title>
    <link rel="stylesheet" href="style.css" />
    <script src="https://unpkg.com/zone.js/dist/zone.js"></script>
    <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
    <script src="config.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>

  <body>
    <my-app>
    loading...
  </my-app>
  </body>

</html>
/* Styles go here */

### Angular Starter Plunker - Typescript
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  paths: {
    'npm:': 'https://unpkg.com/'
  },
  //map tells the System loader where to look for things
  map: {
    
    'app': './src',
    
    '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
    
    '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
    '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
    '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
    
    'rxjs': 'npm:rxjs',
    'typescript': 'npm:typescript@2.0.2/lib/typescript.js'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    rxjs: {
      defaultExtension: 'js'
    }
  }
});
//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';

platformBrowserDynamic().bootstrapModule(AppModule)
//our root app component
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {FirstComponent, SecondComponent, MenuComponent, ChildRouteComponent, HomepageComponent} from './components';
import {DataResolve} from './services';
import {RouterConfig} from './routing';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <app-menu></app-menu>
      <router-outlet></router-outlet>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = 'Angular2'
  }
}

@NgModule({
  imports: [ 
    BrowserModule,
    RouterConfig
  ],
  declarations: [ App, FirstComponent, SecondComponent, MenuComponent, ChildRouteComponent, HomepageComponent ],
  providers: [ DataResolve ]
  bootstrap: [ App ]
})
export class AppModule {
  
}
import {Injectable} from "@angular/core";
import {Subject} from "rxjs/Subject";
import {Observable} from 'rxjs/Observable';
import {Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from "@angular/router";
import 'rxjs/Rx';

@Injectable()
export class DataResolve implements Resolve<any> {
      public constructor(
        private _router: Router
    ) {

    }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any|boolean> {
        let id = +route.params['id'];
        console.log('DataResolve resolve called');
        
        return new Observable<any>(observer => {
            observer.next(id * 2);
            observer.complete();
        });
    }
}
import {ActivatedRoute, Router, NavigationEnd } from "@angular/router";
import {Component, OnDestroy, OnInit, Input} from "@angular/core";
import {Subscription} from "rxjs/Subscription";
import {Observable} from 'rxjs/Observable';
import 'rxjs/Rx';

@Component({
  template: `<h2>Welcome on homepage</h2>`
})
export class HomepageComponent {

}

@Component({
  selector: 'app-menu',
  template: `
    <ul>
      <li>Regular top-level routes
        <ul>
          <li><a [routerLink]="['/first-component', id + 1]">First Component - Parameters</a></li>
          <li><a [routerLink]="['/second-component', id + 1]">Second Component - Data</a></li>
        </ul>
      </li>
      <li>Child routes
        <ul>
          <li><a [routerLink]="['/child/' + (first + 1)]">Change only parent</a></li>
          <li><a [routerLink]="['/child/' + (first + 1) + '/first-component/', id]">First Component - Increment parent</a></li>
          <li><a [routerLink]="['/child/' + (first + 1) + '/second-component/', id]">Second Component - Increment parent</a></li>
        </ul>
      </li>
    </ul>
    <strong>Current id: {{id}}</strong>
    <strong>Current snapshot id: {{snapshotId}}</strong>
  `
})
export class MenuComponent implements OnInit {
  public first = 0;
  public id = 0;
  public snapshotId = 0;
  
    constructor(
      private _activatedRoute: ActivatedRoute,
      private _router: Router
    ) {

    }
  
  ngOnInit():any {
    this._activatedRoute.params.subscribe(params => {
      console.log(params);
      this.id = params['id'] ? params['id'] : 0;
      this.first = params['first'] ? params['first'] : 0;
      
      this.snapshotId = this._activatedRoute.snapshot.params['id'];
    });
  }
}

@Component({
    template: `
    <h2>This is first component!</h2>
    <strong>id: {{data}}</strong>
    <strong>Current snapshot id: {{snapshotId}}</strong>
    <p>OnInit called: {{onInitCalled}} times</p>
    <a [routerLink]="['/first-component', data + 1]">Increment self</a>
    `
})
export class FirstComponent implements OnInit {
    protected data: any;
    static OnInitCalled = 0;
    public snapshotId = 0;

    constructor(
      private _activatedRoute: ActivatedRoute,
      private _router: Router
    ) {

    }
    
    ngOnInit():any {
      FirstComponent.OnInitCalled++;
      console.log('NgOnInit called');
      
      this._router.events.subscribe(event => {
        if (event instanceof NavigationEnd) { 
          this.snapshotId = this._activatedRoute.snapshot.params['id'];
        }
      });
      
      this._activatedRoute.params.subscribe(params => {
        this.data = +params['id'];
        //this.snapshotId = this._activatedRoute.snapshot.params['id'];
      });
    }
    
    get onInitCalled() {
      return FirstComponent.OnInitCalled;
    }
}


@Component({
    template: `
    <h2>This is second component!</h2>
    <strong>id: {{data}}</strong>
    <strong>Current snapshot id: {{snapshotId}}</strong>
    <p>OnInit called: {{onInitCalled}} times</p>
    <a [routerLink]="['/second-component', data + 1]">Increment self</a>
    `
})
export class SecondComponent {
    protected data: any;
    static OnInitCalled = 0;
    public snapshotId = 0;
      
    constructor(
      private _activatedRoute: ActivatedRoute,
      private _router: Router
    ) {

    }
    
    ngOnInit():any {
      SecondComponent.OnInitCalled++;
      console.log('NgOnInit called');
      this._activatedRoute.data.subscribe(data => {
         console.log(data);
         this.data = +data['id'];
         this.snapshotId = this._activatedRoute.snapshot.data['id'];
      });
    }
    
    get onInitCalled() {
      return SecondComponent.OnInitCalled;
    }
}

@Component({
  template: `
  <h2>Submodule</h2>
  <strong>Current id: {{id}}</strong>
  <strong>Current snapshot id: {{snapshotId}}</strong>
  <strong>Current first: {{first}}</strong>
  <strong>Parent first: {{parentFirst}}</strong>
  <a [routerLink]="['./', first + 1, id]">Increment parent</a>
  <router-outlet></router-outlet>
  `
})
export class ChildRouteComponent {
    public first = 0;
    public id = 0;
    public snapshotId = 0;
    public parentFirst = 0;
  
    public activeRoute = null;
  
    constructor(
      private _activatedRoute: ActivatedRoute,
      private _router: Router
    ) {

    }
  
  ngOnInit():any {
    this._activatedRoute.params.subscribe(params => {
      console.log(params);
      this.id = params['id'] ? params['id'] : 0;
      this.first = params['first'] ? params['first'] : 0;
      this._activatedRoute.parent.params.subscribe(parentParams => this.parentFirst = parentParams['first']);
      
      this.snapshotId = this._activatedRoute.snapshot.params['id'];
    });
    
    this._activatedRoute.url.subscribe(url => {
      console.log(url);
    });
  }
}
import { Routes, RouterModule } from '@angular/router';
import { HomepageComponent, FirstComponent, SecondComponent, ChildRouteComponent } from './components';
import { DataResolve } from './services';

export const RouterConfig = RouterModule.forRoot(
  [
    {path: '', component: HomepageComponent},
    {path: 'child/:first', component: ChildRouteComponent, children: [
      {path: ''},
      {path: "first-component/:id", component: FirstComponent},
      {path: "second-component/:id", component: SecondComponent, resolve: {
        id: DataResolve
      }}
    ]},
    {path: "first-component/:id", component: FirstComponent},
    {path: "second-component/:id", component: SecondComponent, resolve: {
      id: DataResolve
    }}
  ], { 
    useHash: true 
  }
);