Tuesday, February 27, 2018

Angualr 5 Trick: include external JS


Angualr 5 Trick: include external JS
This blog first shows how to create an Angular 5 application skeleton, then shows how to call Angular component’s methods from an external JS.

Install angular-cli

npm install -g @angular/cli
(note @, this will install angular versions >4; if omitted, will install angular versions >2)

Create an angular application

ng new AngularTrick

Run application in Webstorm

Click on package.json, and click “show ng scripts”, run “start”.
(I do not use Webstorm to debug javascript, Chrome’s developer tool works out very well)

Create dropdown menu on top

The menu is created with Bootstrap:


To do this, need to import:
"@ng-bootstrap/ng-bootstrap": "1.0.0",
"bootstrap": "4.0.0-alpha.6",

To incorporate bootstrap css styles into the application, in .angular-cli.json, add bootstrap css:
"styles": [
  "styles.css",
  "../node_modules/bootstrap/dist/css/bootstrap.min.css"

],

Create the menu in navbar.component.html:
<nav class="navbar navbar-inverse navbar-toggleable-md jh-navbar">
  <div class="jh-logo-container float-left">
    <a class="jh-navbar-toggler hidden-lg-up float-right" href="javascript:void(0);" data-toggle="collapse"
       data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false"
       aria-label="Toggle navigation" (click)="toggleNavbar()">
      <i class="fa fa-bars"></i>
    </a>

    <a class="navbar-brand logo float-left" routerLink="/" (click)="collapseNavbar()">
      <span class="logo-img"></span>
      <span class="navbar-title">AngularTrick</span>
    </a>
  </div>


  <div class="navbar-collapse collapse" id="navbarResponsive" [ngbCollapse]="isNavbarCollapsed">
    <ul class="navbar-nav ml-auto">
      <li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
        <a class="nav-link" routerLink="/" (click)="collapseNavbar()">
          <i class="fa fa-home" aria-hidden="true"></i>
          <span>Home</span>
        </a>
      </li>


      <li ngbDropdown class="nav-item dropdown pointer" routerLinkActive="active"
          [routerLinkActiveOptions]="{exact: true}">
        <a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="workfloweditor-menu">
                    <span>
                        <i class="fa fa-th-list" aria-hidden="true"></i>
                        <span>
                            AngularTrick
                        </span>
                        <b class="caret"></b>
                    </span> 
        </a>

        <ul class="dropdown-menu" ngbDropdownMenu>
          <li>
            <a class="dropdown-item" [routerLink]="['/trick-external-js-call-angular']" routerLinkActive="active"
               [routerLinkActiveOptions]="{ exact: true }" (click)="collapseNavbar()">
              <i class="fa fa-fw fa-asterisk" aria-hidden="true"></i>
              <span>External JS Call Angular Component Methods</span> 
            </a>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</nav>

And the corresponding navbar.component.ts:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
    selector: 'app-navbar',
    templateUrl: './navbar.component.html',
    styleUrls: [
        'navbar.css'
    ]

})

export class NavbarComponent implements OnInit {
    isNavbarCollapsed: boolean;
    constructor(private router: Router) {
    }

    ngOnInit() {
    }

    collapseNavbar() {
        this.isNavbarCollapsed = true;
    }

    toggleNavbar() {
        this.isNavbarCollapsed = !this.isNavbarCollapsed;
    }

}

In app.component.html, add router-outlet:

<div>
  <router-outlet name="navbar"></router-outlet>
</div>


<div class="container-fluid" style="height: 100%; min-height:100%;">
  <div class="card"  style="height: 100%; min-height:100%;">
    <router-outlet></router-outlet>
    <router-outlet name="popup"></router-outlet>
  </div>
</div>


Add app.route.ts to configure navbar route:

import { Route } from '@angular/router';
import {NavbarComponent} from './navbar.component';

const navbarRoute: Route = {
  path: '',
  component: NavbarComponent,
  outlet: 'navbar'
};



export const LAYOUT_ROUTES = [
  navbarRoute,
];


Import navbar route in app.module.ts:
imports: [
  NgbModule.forRoot(),
  RouterModule.forRoot(LAYOUT_ROUTES, { useHash: true }),
  BrowserModule,
  Trick1Module
],

Include an external javascript into the application

There are two options.

One is to include the file in .angular-cli.json:
"scripts": [
  "./app/outside.js"
],
  
Another approach is to use webpack plugin CopyWebpackPlugin , and copy these files into the target directory, with this approach, you can include the external files in index.html:

new CopyWebpackPlugin([
    {from:'./src/app/outside.js',to:'app/outside.js'},
]}

Call Angular Component’s methods from an external JS

Create a module for this trick:






trick1-main.html shows the following:


 
<div class="row">
  <h3 class="col-lg-12">Trick to include external javascripts and having external javascripts invoking angular component methods</h3>
 </div>

<div class="row">
  <div class="col-lg-12">
  <span>this button will invoke a function from outside.js, which in turn will call an Angular component's method</span>
  </div>

  <div class="col-lg-2">
     <input type="button" value="ExternalJSCallAngualr" onclick="outsideSetHello()"/>
  </div>

  <div class="col-lg-12" *ngIf="showHelloFlag">Hello World</div>

  <div class="col-lg-12" style="margin-top:15px">
    <span>this button will invoke an Angular component's method, which in turn will call an outside javascript</span>
  </div>

  <div class="col-lg-2">
    <input type="button" value="AngularCallOutsideJS" (click)="angularCallOutside()"/>
  </div>

 </div>

The corresponding trick1-main.ts:

import {Component, OnDestroy, OnInit,NgZone} from '@angular/core';
declare var outsideSetHello2: any;


@Component({
    selector: 'external-js-call-angular-main',
    templateUrl: './trick1-main.html',
})

export class ExternalJSCallAngularMainComponent  implements OnInit,OnDestroy {

  showHelloFlag=false;
  showHelloFlag2=false;

  constructor(
    private _ngZone: NgZone){

  }

  ngOnInit() {    

    window['ExternalJSCallAngularMainComponent'] = this;
    this.showHelloFlag2=window['showHelloFlag2'];
  }

  ngOnDestroy() {
    window['ExternalJSCallAngularMainComponent']=null;
  }

  setHelloFlag(){
       this.showHelloFlag=!this.showHelloFlag;
  }

  angularCallOutside(){
    outsideSetHello2();
  }
}


To call a method from an external javascript, declare the method as any:
 
declare var outsideSetHello2: any;

To allow an external javascript call an angular component’s methods, put the component into window global variable:
window['ExternalJSCallAngularMainComponent'] = this;


outside.js contains 2 simple methods:
function outsideSetHello(){
  window["ExternalJSCallAngularMainComponent"].setHelloFlag();
}


function outsideSetHello2(){
  alert("hello world2")
}


3 comments:

  1. Thank you for your post. This is excellent information. It is amazing and wonderful to visit your blog.
    iOS course fee in bangalore
    iPhone training classes in bangalore

    ReplyDelete
  2. AWS Training in Bangalore - Live Online & Classroom
    myTectra Amazon Web Services (AWS) certification training helps you to gain real time hands on experience on AWS. myTectra offers AWS training in Bangalore using classroom and AWS Online Training globally. AWS Training at myTectra delivered by the experienced professional who has atleast 4 years of relavent AWS experince and overall 8-15 years of IT experience. myTectra Offers AWS Training since 2013 and retained the positions of Top AWS Training Company in Bangalore and India.

    IOT Training in Bangalore - Live Online & Classroom
    IOT Training course observes iot as the platform for networking of different devices on the internet and their inter related communication. Reading data through the sensors and processing it with applications sitting in the cloud and thereafter passing the processed data to generate different kind of output is the motive of the complete curricula. Students are made to understand the type of input devices and communications among the devices in a wireless media.

    ReplyDelete