a11y

The planet of accessibility

Accessibility matters

The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect.

 

Sir Tim Berners-Lee

@olivierleplus

Olivier Leplus

 @olivierleplus

DevRel at Microsoft

 Global network of experienced, designers and developers that actively support developers and startups.

Why care ?

Around 1 billion people live with some form of disability.

 

— World health organisation

Law

Why not all websites are accessibles ?

Unfamiliar to lots of developers

Non-trivial

Cheap and Easy

Seman-what?

<div></div>

<span></span>


<a id="addUser" class="btn">
    Add new user
</a>

<button id="addUser" class="btn" aria-label="Add new user">
    Add new user
</button>

Web AIM WCAG Checklists 2.1.1

All page functionality is available using the keyboard, unless the functionality cannot be accomplished in any known way using a keyboard (e.g., free hand drawing).

TIME

TO LEARN ANGULAR 2

ES5

ES2015

ES2016

TS

ES+

Supported Languages

you should learn TypeScript

you must

learn ES6+

bit.ly/learn-es2015 - Discover ES6 (french only)

YOUR APP 

IS A TREE OF

SELF-DESCRIBING

MODULES & COMPONENTS

<my-menu [items]="mainMenu"></my-menu>

<img [src]="imageUrl" />

BINDINGS PROPERTIES

[ prop ]

THREE 

TYPES OF DIRECTIVES

STRUCTURAL

CHANGES THE DOM LAYOUT

<li 
  
  *ngIf="isFooBar"

  *ngFor="let card of dataStore.items; 
            trackBy:customTrackBy">

</li>

STRUCTURAL

<my-items-card *ngFor="let card of dataStore.items; 
                        trackBy:customTrackBy">
  {{ card }}
</my-items-card>


<!-- is equivalent to this -->
<template ngFor let-card [ngForOf]="dataStore.items" 
                      [ngForTrackBy]="customTrackBy">
  <my-items-card>{{ card }}</my-items-card>
</template>

STRUCTURAL ATTRIBUTES

*ngFor

ATTRIBUTES

CHANGES THE BEHAVIOR OF THE ELEMENT

<div

  [style.width.px]="mySize">

</div>

ATTRIBUTES

ATTRIBUTE DIRECTIVE

import {
  Directive, 
  ElementRef, 
  Renderer, 
} from '@angular/core';

@Directive({
  selector: '[myHighlight]'
})
export class MyHighlightDirective {
  constructor(el: ElementRef, renderer: Renderer) {
    renderer
        .setElementStyle(
            el.nativeElement, 
            'backgroundColor', 
            'yellow'
        );
  }
}
<span myHighlight >Highlight me!</span>
import {Directive, ElementRef, Renderer} from '@angular/core';

@Directive({
  selector: '[x-large]'
})
export class XLarge {
  constructor(element: ElementRef, renderer: Renderer) {

    renderer.setElementStyle(
        element.nativeElement, 'fontSize', 'x-large'
    );

  }
}

DO NOT EVER NEVER TOUCH THE DOM!

USE THE RENDERER

renderer.setElementStyle(
    el.nativeElement, 
    'backgroundColor', 
    'yellow'
);

COMPONENT

JUST A DIRECTIVE WITH A TEMPLATE

<my-component>
  Loading...
</my-component>

COMPONENT

COMPONENTS CAN DISPLAY FORMATTED DATA

THANKS TO

PIPES

JUST LIKE 

ANGULAR 1

FILTERS

BUILT-INS PIPES

DatePipe, 

UpperCasePipe, 

LowerCasePipe, 

CurrencyPipe,

PercentPipe...etc

CUSTOM PIPE

import {Pipe, PipeTransform} from '@angular/core';

@Pipe({
  name: 'trim'
})
export class TrimPipe implements PipeTransform {
  transform(value: any) {
    if (!value) {
      return '';
    }
    return value.trim();
  }
}

PIPES CAN BE STATEFUL

ASYNC PIPE

import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
  name: 'fetch',
  pure: false
})
export class FetchJsonPipe {
  private fetchedValue:any;
  private fetchPromise:Promise<any>;

  transform(value:string, args:string[]):any {
    this.fetchPromise = window.fetch(value)
      .then((result:any) => result.json())
      .then((json:any)   => this.fetchedValue = json);
    
    return this.fetchedValue;
  }
}

ASYNC PIPE

<div>
  {{'heroes.json' | fetch | json}}
</div>

COMPONENTS

CAN HAVE

STATE

STATE MANAGMENT

[ property binding ]

( event binding )

import {Component, Input, AfterViewInit, EventEmitter} from '@angular/core';
@Component({
    /* configuration */
})
export class ThemeCard implements AfterViewInit {

  @Input() inputProperty: string;

  @Output() outputEvent: EventEmitter<string>;

  constructor() {
    this.outputEvent = new EventEmitter<string>();
  }

  ngAfterViewInit() {
    console.log(this.inputProperty);
  }
  onClick() {
    this.outputEvent.emit('foo');
  }

}

FOR INSTANCE

COMPONENTS ARE

ROUTABLE

DEFINING ROUTES

// app.routes.ts

import { RouterModule } from '@angular/router';
import { CatComponent } from './cats/';


const routes = [
  {path: '', redirectTo: 'cat'},
  {path: 'cat', component: CatComponent}
];


export const Routes = RouterModule.forRoot(routes);
// app.routes.ts

import { RouterModule } from '@angular/router';
import { CatComponent } from './cats/';


const routes = [
  {path: '', redirectTo: 'cat'},
  {path: 'cat', loadChildren: 'app/cat/cat.module#CatModule'}
];


export const Routes = RouterModule.forRoot(routes);

LAZY LOADING

// app.routes.ts

import { RouterModule } from '@angular/router';
import { CatComponent, AuthGuard, CatResolver } from './cats/';


const routes = [
  {path: '', redirectTo: 'cat'},
  {
    path: 'cat', 
    canActivate: [ AuthGuard ],
    resolve: { cats: CatResolver },
    loadChildren: 'app/cat/cat.module#CatModule'
  }
];


export const Routes = RouterModule.forRoot(routes);

ROUTES GUARDS

REGISTERING ROUTES

import { NgModule } from '@angular/core';
import { Routes } from './app/app.routes';

@NgModule({
    imports: [ ..., Routes ],
    ...
})

COMPONENT ROUTER

// app.component.ts

@Component({ 
  selector: 'my-app',
  template: `
  <h1>Component Router</h1>
  <nav>
    <a [routerLink]="['cat']">Cat</a>
  </nav>
  <router-outlet></router-outlet>
  `
})
export class AppComponent {
    constructor() {}
}

COMPONENTS CAN USE 

SERVICES

import { Component } from '@angular/core';
import { DataStore } from './my-store.service';

@Component({
  selector: 'home',

  providers: [ DataStore ],

  //...
})
export class Home {

  private data: any[];

  constructor(data: DataStore){
    this.data = data.someAPI();
  }

}

LOCAL SERVICES

import { NgModule } from '@angular/core';
import { DataStore } from './my-store.service';

@NgModule({
    providers: [ ..., DataStore ],
    ...
})

GLOBAL SERVICES

PROVIDERS CONFIGURATION

import { Component, provide } from '@angular/core';
import { DataStore } from './my-store.service';

@Component({
  providers: [ DataStore ]
})
export class Home { /*  */ }
{ provide: DataStore, useClass: DataStore }
// values
{provide: Token, useValue: 'Hello World' }

// aliases
{provide: DataStore, useClass: DataStore }
{provide: MockedDataStore, useExisting: DataStore }


// factories or configurable instances
{provide: DataStore, useFactory: (dep1, dep2) => {
    return new DataStore(dep1, dep2);
  },
  deps: [Dep1, Dep2]
}

PROVIDERS CONFIGURATION

CONCEPTS RECAP

COMPONENTS •

STATE • LIFE CYCLES

TEMPLATE SYNTAX • DIRECTIVES • PIPES  • ROUTER • PROVIDERS/DI

OTHER COOL FEATURES

HTTP • ANIMATIONS • FORMS • MATERIAL DESIGN • I18N • WEB WORKER • RX/OBSERVABLES • SERVER SIDE RENDERING...

TOOLINGS TECHNOLOGIES

SUPPORTED LANGUAGES

EDITORS SUPPORT

Angular2 and TypeScript support

BUILD SYSTEMS

CHECK OUT THE NEW ANGULAR CLI

MIGRATION STRATEGIES

1  • Following The Angular Style Guide

2 • Using a Module Loader

3 • Migrating to TypeScript

4 • Using Component Directives

Preparation: ng1→ng2+

Upgrading with The Upgrade Adapter

Upgrading with The Upgrade Adapter

UPGRADING TO ANGULAR 2+ OFFICIAL DOCUMENTATION

(click on icon to open link)

COMMUNITY FEEDBACK

THANKS TO FELLOW GDEs

BENEFITS

Faster development and errors prevention, thanks to Classes, TypeScript and Decorators...

DRAWBACKS

Set up the build system can be hard...

We have a CLI...

BENEFITS

Faster change detection (up to 10x times faster) and faster overall performance (up to 2.5x times or more)...

DRAWBACKS

People don't seem to like the template syntax...

Com'on, this is just syntax.

BENEFITS

Future proof with support for web, mobile, server-side rendering and native...

DRAWBACKS

Lack of convention?

The Style guides are here!

BENEFITS

Great browser support. Internet Explorer 9 and plus...

DRAWBACKS

Some developers are turned off by Dependency Injection...

sorry for you guys!

BENEFITS

No long tied to the browser. Angular 2+ can run anywhere (server, mobile, web worker, etc.)...

SOME THOUGHTS...

A2 has all the concepts of A1 but is better in every way...

Your skills from A1 have already prepared you for A2...

John Papa

Ng2 is built upon Web Standards, if you know the Web then you know ng2...

Ng2 is not just a framework, it is a modular platform.

Angular 2 Bible

NgConf 2016

AngularConnect 2016

Angular 2+ Resouces

manekinekko

A11y, the planet of accessibility

By Olivier Leplus

A11y, the planet of accessibility

  • 884