Saturday 28 January 2017

Project Migration to Angular 2: Bootstrap Part 1

The migration of a working application to a more recent platform brings some risks. Generally, some functions cannot be reproduced as is and it takes many times. I wish to move a simple client, programmed using a mix of JavaScript and AngularJS, to Angular 2.

Platform

The platform is the same as in the previous post. I work on a Windows 10 workstation using the Atom (1.12.9) editor with the typescript plugin (10.1.13) and NodeJS (7.4.0). I'm using Angular-Seed as basic setup for the project.

Template

I use Bootstrap (3.3.7) as a template for my client. Moving from JavaScript to AngularJS I tried to move the existing code to AngularJS. This was and is a mistake. I was a beginner in AngularJS and I lost a lot of time to redo something which was already well done. Now I go a step back and try to enhance my original JavaScript based application using Angular 2.

I have to add Bootstrap to the package.json file into the project root. Since Bootstrap uses jQuery I must add it too.


  "dependencies": {
    "@angular/common": "~2.4.0",
    "@angular/compiler": "~2.4.0",
    "@angular/core": "~2.4.0",
    "@angular/forms": "~2.4.0",
    "@angular/http": "~2.4.0",
    "@angular/platform-browser": "~2.4.0",
    "@angular/platform-browser-dynamic": "~2.4.0",
    "@angular/router": "~3.4.1",
    "bootstrap": "^3.3.0",
    "core-js": "^2.4.1",
    "intl": "^1.2.5",
    "jquery": "^3.0.0",
    "rxjs": "~5.0.3",
    "systemjs": "0.19.41",
    "zone.js": "^0.7.2"
  }

>npm install

Bootstrap is placed under <project>/node_modules/bootstrap/dist. The CSS files

bootstrap.css
bootstrap-theme.css

must be copied to the folder <project>/src/client/css. The entire fonts sub folder must be copied to <project>/src/client.

Angular-Seed needs to know about the new files CSS and JS files. I added some code to the file


    // Add `NPM` third-party libraries to be injected/bundled.
    this.NPM_DEPENDENCIES = [
      ...this.NPM_DEPENDENCIES,
      {src: 'jquery/dist/jquery.min.js', inject: 'libs'},
      {src: 'bootstrap/dist/js/bootstrap.min.js', inject: 'libs'},
    ];

    // Add `local` third-party libraries to be injected/bundled.
    this.APP_ASSETS = [
      ...this.APP_ASSETS,
      {src: `${this.CSS_SRC}/bootstrap.css`, inject: true, vendor: false},
      {src: `${this.CSS_SRC}/bootstrap-theme.css`, inject: true, vendor: false},
    ];

placed under <project>/tools/config.

>npm start

Now let's do some changes in the Angular-Seed application.

  • Remove the <sd-toolbar> tag from app.component.html
  • Replace the content of main.css


.bs-nav {
  background-color: #fff;
  border-bottom: 0;
  margin-bottom: 0;
}

  • Remove the CSS :host from navbar.component.css
  • Replace the content of navbar.component.html


<header class="bs-nav navbar navbar-inverse navbar-static-top">
  <div class="navbar-header">
    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-navbar-collapse-1" aria-expanded="false">
      <span class="sr-only">Toggle navigation</span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </button>
    <a class="navbar-brand" [routerLink]="['/']">Bootstrap Seed</a>
  </div>
  <div class="collapse navbar-collapse" id="bs-navbar-collapse-1">
    <ul class="nav navbar-nav">
      <li [routerLink]="['/']"      [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"><a [routerLink]="['/']">Home<span class="sr-only">(current)</span></a></li>
      <li [routerLink]="['/about']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"><a [routerLink]="['/about']">About</a></li>
      <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
        <ul class="dropdown-menu">
          <li><a [routerLink]="['/admin/info']">Info</a></li>
          <li><a [routerLink]="['/admin/metrics']">Metrics</a></li>
          <li><a [routerLink]="['/admin/trace']">Trace</a></li>
        </ul>
      </li>
    </ul>
  </div>
</header>

The application remains the same but uses the bootstrap navigation bar as is. Bootstrap is a HTML/CSS template with some JavaScript, this make the project suitable for the integration with Angular 2. At this point of my investigation I'm not sure that all details will work, but I'm confident it will.

The entire project is on GitHub

No comments:

Post a Comment