Angular 2 is coming!



Angular 2 is coming!

0 2


angular-2-alpha

Angular 2 intro - code examples in /live-code, talk given at JS-Monthly, 2015

On Github timruffles / angular-2-alpha

Angular 2 is coming!

@timruffles @sidekicksrc

Angular 2 is still in the works. The core concepts are solid, but the API may change

Victor Savkin, 12th Oct.

But...

Google in production

Fiber launched this week as Google's first Angular 2 application. https://t.co/CgOIiuq13U pic.twitter.com/hsKlpHA4y6

— Brad Green (@bradlygreen) November 20, 2015

Big goals

Components

Dependecy Injection

Evolution from ng1

Components

Our first component

import { Component } from 'angular2/angular2';

export { HelloComponent };

@Component({
  selector: 'hello-angular',
  template: '<h1>{{ message }}</h1>',
})
class HelloComponent {
  constructor() { 
    this.message = "Hi there";
  }
}

Woah!

Bit by bit

import { Component } from 'angular2/angular2';

export { HelloComponent };

@Component({
  // any CSS selector
  selector: 'hello-angular',
  // ...
})

@Component({
  // ...
  template: '<h1>{{ message }}</h1>',
})

class HelloComponent {
  constructor() { 
    this.message = "Hi there";
  }
}

All together

import { Component } from 'angular2/angular2';

export { HelloComponent };

@Component({
  selector: 'hello-angular',
  template: '<h1>{{ message }}</h1>',
})
class HelloComponent {
  constructor() { 
    this.message = "Hi there";
  }
}

That's an app!

import { HelloComponent } from "./HelloComponent";
import { bootstrap } from "angular2/angular2";

bootstrap(HelloComponent);
<!DOCTYPE html>
<hello-component></hello-component>
<!-- with a production bundle -->
<script src="dist/app.js"></script>

Hierarchy

import { Component } from 'angular2/angular2';
import { HelloComponent } from './HelloComponent';

export { FrontPage };

@Component({
  selector: 'front-page',
  directives: [HelloComponent],
  template: '<hello-angular></hello-angular>',
})
class FrontPage {
}

Explicit

import { Component, FORM_DIRECTIVES, CORE_DIRECTIVES }
 from 'angular2/angular2';

@Component({
  directives: [FORM_DIRECTIVES, CORE_DIRECTIVES],
  // ...
})

New template syntax

Data binding

<!-- like ng 1 - interpolated -->
<div title="Hello {{ person }}">
<!-- whole attribute -->
<div [title]="getMessage()">

Pipes (new name for filters)

<div [title]="getMessage() | toTitle">

Event-handling

<!-- DOM events -->
<form (submit)="create($event)">

Two-way data-binding

<!-- the local ourName property will be two way bound to <code>name</code>
     of our some-editor component -->
<some-editor ([name])="ourName">

Local variables

<video #movieplayer >
  <button (click)="movieplayer.play()">
</video>

Let's have a go

Better DI

First: why DI?

Two benefits

One: testing

Two: multiple implementations

Angular 1

Crufty

module.service("User", calledWithNew);
module.factory("User", usesReturnValue);
module.provider("User", returnsProviderConfig);
module.value("User", User);

Implicit

  • e.g 'where did this service come from?!'
  • file location opaque
module.controller("UserCtrl", function(
  User
  , Login
  , errors
) {
  // unclear where the above came from physically
  // (without conventions)
})

App-wide

  • Can't switch provider for part of an app

Angular 2

Let's define a 'service'

Oh

export { Greeter };

class Greeter {
  message(name) {
    return 'Hello ${name}, 
      Angular 2 is easy';
  }
}

Using a service

Better API

import { Component } from 'angular2/angular2';
import { Greeter } from './greeter';

@Component({
  // setup
  providers: [Greeter],
})
class HelloComponent {
  constructor(greeter: Greeter) { 
    this.message = greeter.message();
  }
}

Hierarchical

import { Greeter } from './greeter';

bootstrap(FrontPage, [Greeter]);
import { Greeter } from './greeter';

@Component({
  // don't be explicit
  providers: [],
})
class HelloComponent {
  constructor(greeter: Greeter) { 
  }
}

Tree

Let's have a go

Evolution

1.5

  • new module.component method
  • aiming for Jan

ngUpgrade

  • can run ng 1 and ng 2 in parallel

Learning from 1.x

Routing

Component Router

  • 1.x and 2.x

Structured

Let's have a go

Performance

Pre-compilation

  • reduces load and run cost

Web-workers

  • only UI updates run in main thread
  • does require certain constraints

Mobile

Native Script

Predicability

ng 1 change detection

$scope

Behind the scenes

$apply()

  • library authors: wrap all async
// rought version of ng-click
el.on("click", function(event) {
  $scope.$apply(function() {
    $scope.$eval(userCallback, {
      $event: event,
    });
  });
});

Pretty good, still nasty

ng 2: no $scope

Zones!

@Component({
  selector: 'toggler',
  template: '<button (click)="toggle()">
    {{ msg }}</button>',
})
class TogglerComponent {
  constructor() { 
    this.msg = "Click me";
  }
  toggle() {
    this.msg = "You clicked me!";
    setTimeout(() => { 
      this.msg = "Click me";
    }, 250);
  }
}

How?

Patching

Zones patch all async:

window.setTimeout = function(fn, timeout) {
  originalTimeout(zone.callback(fn), timeout);
}

MOAR!!!

  • RxJS support
  • Immutables via controlling updates
  • ES.next support, non-TypeScript

ng2 summary

Broad goals

Components Better DI Evolution: router, animation, tests etc

vs ng1, ng2 apps:

Better isolation of components More maintainable: ability to swap out services locally Predictable: immutability, one-way data-flow Better: powerful routing, animation

Links

Thanks!

@timruffles