Craft cross framework Components using

Angular

@pankajparkar

.

.

etc.

Pankaj Parkar

Technical Lead

Synerzip Softech India PVT LTD

  • Microsoft MVP
  • Opensource Contributor
  • Stackoverflow Topuser for Angular and AngularJS
  • 100k+ points on Stackoverflow
  • .Net and Angular Developer
  • Currently working on MERN & GraphQL

@pankajparkar

Angular is ideal for building complete applications

Rob Wormald, Angular Team

But it becomes challenging for scenarios that don't fit in Single Page Application Model

@pankajparkar

Challenges

  1. Reusability of code (cross platform)

  2. Enhance existing application

  3. Content Management System pages

  4. Embed Widgets inside another app

@pankajparkar

Running Angular on Mixed environment

  • AngularJS
  • React
  • Polymer 
  • jQuery
  • Aurelia
  • Vue
  • Vanilla JS
  • etc..

@pankajparkar

Angular components are tough to use outside Angular

Rob Wormald, Angular Team

@pankajparkar

Why you want to use Angular outside?

@pankajparkar

Ecosystem

Can we use something that follow Web Standards and address our issue?

Web Component

@pankajparkar

Before moving further, lets flashback

@pankajparkar

HTML 1

HTML 2

(1990)

INPUT   FORM  SELECT

@pankajparkar

BODY   A  H2   IMG   UL   LI

(1995)

HTML 5

@pankajparkar

INPUT    FORM    SELECT

BUTTON   VIDEO   AUDIO

DIALOG   CANVAS   TEXTAREA

DATALIST   IMG   PROGRESS

Input had 8 types when it got introduced

Now input have 22 types

Unix

@pankajparkar

(1970)

ls

lpr

cat

grep

sort

chmod

echo

alias

less

more

head

who

time

find

tail

echo

kill

mkdir

pwd

ps

.
.

Do One Thing and Do It Well

Unix Philosophy

source: https://en.wikipedia.org/wiki/Unix_philosophy

  • Write programs that do one thing and do it well.
  • Write programs to work together.
  • Write programs to handle text streams, because that is a universal interface.
  • Output of one program should become input for other.

Web Component

  1. Template
  2. Shadow DOM
  3. Html Imports
  4. Custom Elements

@pankajparkar

Web Components are a set of features currently being added by the W3C to the HTML and DOM specifications that allow for the creation of reusable widgets or components in web documents and web applications.

Specs

1. Template

<template id="content">
  <h1>Hello World!</h1>
  <img src="success.jpg" />
  <script> 
    //some big javascript 
  </script>
</template>
var content = document.getElementById('content');
var div = document.createElement('div');
var clone = document.importNode(template.content, true);
document.body.appendChild(div);

@pankajparkar

We have similar technique, that used inside `ng-template`

2. Shadow DOM

<body>
  <div>
    <#shadow-root>
      <h1 class=”title”></h1>
    </shadow-root>
  </div>
</body>

We can do this for component using viewEncapsulation set to Native.

@pankajparkar

<body>
    <div>Hello, World!</div>
    <script>
      var host = document.querySelector(‘div’);
      var root = host.createShadowRoot();
      root.textContent = ‘Hello, Treehouse!’;
    </script>
</body>

3. HTML Imports

<head>
   <link 
    rel="import" 
    href="my-widget.html" />
</head>

This spec is deprecated, this is not going to implement by browsers.

@pankajparkar

4. Custom Element

<body>
  <my-navbar></my-navbar>
  <div class="content">
    <my-sidebar></my-sidebar>
    <my-main-content></my-main-content> 
  </div>
  <my-footer></my-footer>
</body>

@pankajparkar

Custom Element

  • Standard way of defining web component
  • Extend the browser vocabulary

Custom element should have dash used in their name, they can't be single word

@pankajparkar

Web Component Support

@pankajparkar

Custom Elements

class FancyDatePicker extends HTMLElement {}

window.customElements
  .define(‘fancy-datepicker’, FancyDatePicker);

@pankajparkar

It has below native DOM objects

  1. Attributes

  2. Events

  3. Properties

  4. Method

@pankajparkar

Custom Elements - Attributes

class FancyDatePicker extends HTMLElement {

  static observedAttributes = [‘current-date’];

  attributeChangedCallback(oldV, newV, key){
    //update the DOM somehow
  }
}
<fancy-datepicker 
  current-date=”10/10/2017”>
</fancy-datepicker>
const picker = document.querySelector(‘fancy-datepicker’);
picker.setAttribute(‘current-date’, new Date().toString());

Declarative

Imperative

@pankajparkar

Custom Elements - Properties

class FancyDatePicker extends HTMLElement {

  set currentDate(value){
    //update the DOM
  }

  get currentDate(){ … }  
}
const fancyDatePicker = 
    document.querySelector(‘fancy-datepicker’);
fancyDatePicker.currentDate = new Date();

@pankajparkar

Custom Elements - Event

const picker = document.querySelector(‘fancy-datepicker’);

const onDateChange = (date) => console.log(date);
picker.addEventListener(‘date-change’, onDateChange);

@pankajparkar

Custom Elements - Method

class FancyDatePicker extends HTMLElement {
  emitDateChange(details){
    let dateChangeEv = 
       new CustomEvent(‘date-change’,{details});
    this.dispatchEvent(dateChangeEv);
  } 
}
const fancyDatePicker = 
     document.querySelector(‘fancy-datepicker’);
fancyDatePicker.emitDateChange(); //calling method

@pankajparkar

Usage

Custom Elements - Reactions /Lifecycle Hooks

class FancyDatePicker extends HTMLElement {

  connectedCallback(){ … }

  disconnectedCallback(){ … }

  attributeChangedCallback(oldV, newV, key){ … }

  adoptedCallback(){ … }

}

@pankajparkar

Web Component works out of the box in Angular, it supports by design

<my-angular-app>
  <my-input
    [attr.foo]=”someString”
    [someProp]=”someProp”
    (someEvent)=”doStuff()”>
   </my-input>
</my-angular-app>

Angular with Web Component

@pankajparkar

Then why not use Web Components?

Text

https://developers.google.com/web/fundamentals/web-components/examples/howto-checkbox

Source: http://pascalprecht.github.io/slides/angular-elements/#/14

@pankajparkar

Angular API looks similar to CE

NG

CE

@HostBindings

@Input

@Output

@Lifecycle Hooks

Attributes

Properties

CustomEvent

Reactions

@pankajparkar

@pankajparkar

Angular Elements

Angular Elements

  • Export Angular Components as custom-element that can re-usable on any application
  • Self bootstrapping
  • Follow current web standard
  • Now zone is optional since Angular version 5

Angular Component packaged as web component

@pankajparkar

web-component

Component

Angular Elements API

Component

Even other guys are doing it

SkateJS

@pankajparkar

How to setup Angular elements

// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector, Type } from '@angular/core';
import { createCustomElement } from '@angular/elements';

import { HelloWorldComponent } from './hello-world';
export const CEComponents = [HelloWorldComponent];

@NgModule({
  imports: [BrowserModule],
  declarations: CEComponents,
  //Step 1: Include all Custom elements here
  entryComponents: CEComponents
})
export class AppModule { 
  constructor(private injector: Injector){
    //Step 2: Register CEs here with module Injector
    const customElement = createCustomElement(VoteComponent, 
       { injector: this.injector }
    );
    customElements.define('vote-cmp', customElement);
  }
  ngDoBootstrap(){ }
}

@pankajparkar

Demo Time

  • Angular with CE Component - Demo
  • ReactJS - Demo

@pankajparkar

How it look in general

<html>
  <head>
    ...
    ...
    <script src="my-customelement.bundle.js"></script>
    ...
  </head>
  <body>
    ...
    <my-ng-component></my-ng-component>
    ...
  </body>
</html>

@pankajparkar

Where is it heading?

<html>
  <head>
    ...
    ...
    <script src="angular-mini.js"></script>
    <script src="my-custom-element.bundles.js"></script>
    ...
  </head>
  <body>
    ...
    <my-ng-component></my-ng-component>
    ...
  </body>
</html>

@pankajparkar

jQuery datepicker

Jquery dialog modal example

<html>
  <head>
    ...
    ...
    <script src="jquery.js"></script>
    <script src="jquery.datepicker.js"></script>
    ...
  </head>
  <body>
    ...
    <input id="my-datepicker" />
    <script type="javascript">
       $('#my-datepicker').datePicker({
         format: 'dd-MM-yyyy'
       })
    </script>
    ...
  </body>
</html>

@pankajparkar

Future?

Angular Ivy Renderer (beta) +

Angular Elements

@pankajparkar

@pankajparkar

Q & A

References

  • https://blog.angular.io/the-angular-team-at-angularmix-2d56fd7fde65

  • https://github.com/angular/angular/issues/21706

  • http://slides.com/andreiantal/ng-europe_angular-elements#/33

  • http://slides.com/andreiantal/ng-europe_angular-elements#/3

  • https://github.com/andrei-antal/ng-europe-demo-angular-elements (Thanks Andrei Antal)

  • https://github.com/pankajparkar/ng-india-angular-elements-demo

  • https://github.com/pankajparkar/ng-india-vueapp

  • https://github.com/pankajparkar/ng-india-reactapp

  • https://medium.com/@ezekizibzibadze/angular-and-web-components-a-k-a-angular-elements-e009b057cd75

  • https://en.wikipedia.org/wiki/Unix_philosophy

Craft cross framework Components using Angular

By Pankaj Parkar

Craft cross framework Components using Angular

  • 1,420