#ngeurope @CarmenPopoviciu @PascalPrecht

"Don't stop thinking about tomorrow"

AngularJS and Web Components

By Carmen Popoviciu and Pascal Precht a.k.a ng-duo

Miško Hevery

Shared publicly - Aug 1, 2013

Ever wonder why AngularJS is super-heroic? It is because our interns are superheroes.

Carmen Popoviciu

Shared publicly - Oct 23, 2014

Ever wonder why the Angular community is so awesome? Because it has superheroes as well.

+1

Web Components

Web Components are a collection of standards that change the way we build web applications.

Four Technologies

  • HTML Templates - Inert chunks of clonable DOM

  • Shadow DOM - Style & DOM encapsulation

  • Custom Elements - Define and use new DOM elements

  • HTML Imports - Include other HTML documents

Four Technologies

  • HTML Templates - Inert chunks of clonable DOM

  • Shadow DOM - Style & DOM encapsulation

  • Custom Elements - Define and use new DOM elements

  • HTML Imports - Include other HTML documents

Inert chunks of clonable DOM that can be activated for later use.

Defining templates

<template id="mytemplate">
  <img src="" alt="great image">
  <div class="comment"></div>
</template>
  • Clonable DOM
  • Parsed, not rendered
  • Stylesheets/Images aren't loaded, media isn't played, scripts don't run

Activating templates

var t = document.querySelector('#mytemplate');

// set image source
t.content.querySelector('img').src = 'logo.png';

// clone and append document fragment
document.body.appendChild(t.content.cloneNode(true));

You can activate templates by cloning their content document fragment.

Four Technologies

  • HTML Templates - Inert chunks of clonable DOM

  • Shadow DOM - Style & DOM encapsulation

  • Custom Elements - Define and use new DOM elements

  • HTML Imports - Include other HTML documents

Four Technologies

  • HTML Templates - Inert chunks of clonable DOM

  • Shadow DOM - Style & DOM encapsulation

  • Custom Elements - Define and use new DOM elements

  • HTML Imports - Include other HTML documents

Shadow DOM gives us DOM tree encapsulation and style boundaries.

<input type="time">

Creating Shadow DOM

.createShadowRoot() creates a shadow root on a host element.

<div>Hello World!</div>
var host = document.querySelector('div');
var shadowRoot = host.createShadowRoot();
shadowRoot.innerHTML = 'Hello ngEurope!';

Shadow DOM + HTML Templates

Simply combine the things we just learned.

var host = document.querySelector('#host');
var shadowRoot = host.createShadowRoot();
var t = document.querySelector('#custom-template');

shadowRoot.appendChild(t.content.cloneNode(true));

So much more to cover

  • Insertion Points/Content Projection using <content>
  • Shadow host styling with :host, :host(selector), :host-context(selector)
  • Shadow tree stying with ::shadow and /deep/
  • Multiple shadow roots and <shadow>

Four Technologies

  • HTML Templates - Inert chunks of clonable DOM

  • Shadow DOM - Style & DOM encapsulation

  • Custom Elements - Define and use new DOM elements

  • HTML Imports - Include other HTML documents

Four Technologies

  • HTML Templates - Inert chunks of clonable DOM

  • Shadow DOM - Style & DOM encapsulation

  • Custom Elements - Define and use new DOM elements

  • HTML Imports - Include other HTML documents

Custom Elements allow web developers to define new types of HTML elements.

Registering new elements

document.registerElement('custom-element', {
  prototype: Proto
});

document.registerElement() let's you register custom elements.

Protoype definition

var Proto = Object.create(HTMLElement);

Proto.fooProperty = 'bar';

Proto.createdCallback = function () { 
  /* e.g. create shadow root */
};

Proto.attributeChangedCallback = function (name, old, new) { 
  /* ... */
};

Instantiate Custom Elements

Or

var myElement = document.createElement('custom-element');
document.appendChild(myElement);

Four Technologies

  • HTML Templates - Inert chunks of clonable DOM

  • Shadow DOM - Style & DOM encapsulation

  • Custom Elements - Define and use new DOM elements

  • HTML Imports - Include other HTML documents

Four Technologies

  • HTML Templates - Inert chunks of clonable DOM

  • Shadow DOM - Style & DOM encapsulation

  • Custom Elements - Define and use new DOM elements

  • HTML Imports - Include other HTML documents

#include for the web

Usage

<link rel="import" href="path/to/import.html">

Use <link rel="import"> to import external HTML documents.

Cloning contents into main document

var link = document.querySelector('link[rel="import"]');
var content = link.import;
          
var el = content.querySelector('.widget');

document.body.appendChild(el);

The imports .import property can be used to query DOM objects.

Putting it all together

<x-ngduo></x-ngduo>

AngularJS & Web Components

Web Components inside Angular world

Could look like this...

Web Components inside Angular world

...or like this:

Angular doesn't know and shouldn't know about custom elements.

Data binding

  • Writing data (Angular → Custom Element)
  • Reading data (Angular ← Custom Element)

Data binding - writing data

  • Angular detects the change using its own internal mechanism
  • Angular reflects the change into the elements attribute or property
  • Element processes the change

Data binding - reading data

  • Element notifies the outside world that it's state has changed
  • Angular processes the change

So how do custom elements actually notify the outside world?

A custom element can change DOM attributes or Element properties.

  • DOM attributes changes can be detected using DOM Mutation Observers
  • Element properties changes will be detected most likely using events

AngularJS + Web Components

(tomorrow)

Warning!

Everything in this section is based on wip documents. Things might change in the future.

(Do not try this at home!)

← Igor Brian →

So how does Angular 2.0 tackle the existing issues in the future?

Binding to properties

var ngDuoProto = Object.create(HTMLElement.prototype, {
  // Element properties
  sources: { 
    get: function() {...},
    set: function(value) {...}
  }
});
          

The syntax proposal for property binding is "[ ]"

Event Binding

One syntax proposal is to wrap event names in "( )"

Thanks!

pascalprecht.github.io/dont-stop-thinking-about-tomorrow

By Carmen Popoviciu and Pascal Precht a.k.a ng-duo