Try Angular 2

- Alpha-20 -

Angular Korea Meetup

May 2nd, Google Campus Seoul

Change is Good

Collaboration & Sharing



React

React

  • Package Manager
  • Tools
Ember

Ember

  • Router
  • Ember-cli
TypeScript

TypeScript

  • @Annotations
  • ES6, ES7

Web Standards



Web Components

  • HTML Imports
  • <template>
  • Shadow DOM

ES6+

  • Imports
  • Classes
  • Observables
  • More

Less Framework Specific

  • Factory, Service, Constant, etc.
  • Link, Compile, Controller
  • $scope, ng-everything

Split in Two:

Application
Layer

View
Layer



Resulting Awesomeness: Web Workers | Server Rendering | Native Apps | Better Change Detection | Easier Testing

Project: TodoMVC

TodoMVCAngular

ES6 Modules


        import {bootstrap, Component, View} from 'angular2/angular2';
      

angular.module('app', ['Dependency'])

ES6 Classes


        class TodoApp {}
      

Directive Controller

@Component


        @Component({
          selector: 'todo-app’
        })
        class TodoApp {}
      

Directive with template + Controller

@View


        @Component({ ... })
        @View({
          template: `<h1>{{title}}</h1>` // or:
          //templateUrl: 'todos.html'
        })
        class TodoApp { ... }
      

Directive Template/TemplateUrl

bootstrap(class)


        @Component({ selector: 'todo-app’ })
        @View({ template: `<h1>{{title}}</h1>` })
        class TodoApp {}

        bootstrap(TodoApp);
      


        <todo-app></todo-app>
      

angular.module('app', ['Dependency'])

<body ng-app="todo-app">

Class Constructor


        @Component({ selector: 'todo-app’ })
        class TodoApp {
          // initial values
          constructor() {
            this.todos = ['First thing', 'Second thing', 'Third thing'];
          }
        }
      

Controller

Class Methods


        export class TodoStorage {
          // initial values
          constructor () {
            this.STORAGE_ID = 'todos-angular2';
          }

          // methods
          get() {
            return JSON.parse(localStorage.getItem(this.STORAGE_ID) || '[]');
          }
          put(todos) {
            localStorage.setItem(this.STORAGE_ID, JSON.stringify(todos));
          }
        }
      

Singletons: Controller, Service, Factory, Directive

Inject Services


        import {TodoStorage} from 'todoStorageService';

        @Component({
          selector: 'todo-app',
          injectables: [ TodoStorage ]
        })
        class TodoApp {
          constructor(storage: TodoStorage) {
            this.todos = storage.get() || [];
          }
        }
      

function TodoCtrl(TodoStorageService) {}

Template Syntax

#Local Variables


         <input #new-todo>
       

ng-init

{{ binding }}


        <input #new-todo />
        <p>{{newTodo.value}}</p>
      

(event)="statement"


        <input #new-todo (keydown)>
      


        <input #new-todo (keydown)=“addTodo($event, newTodo.value)”>
      

ng-keydown=($event, newTodo)

ng-* => (event)

  • ng-click => (click)
  • ng-dblclick => (dblclick)
  • ng-keydown => (keydown)
  • ng-keyup => (keyup)
  • ng-mouseover => (mouseover)
  • ng-mouseenter => (mouseenter)
  • ng-mouseleave => (mouseleave)

[property]="expression"


        <ul>
          <li [style.background-color]=“newTodo.value”>
            {{newTodo.value}}
          </li>
        </ul>
      

ng-style="{'background-color':newTodo}">

ng-* => [property]

  • ng-src => [src]
  • ng-href => [href]
  • ng-show => [visible]
  • ng-hide => [hidden]
  • ng-style="color: red" => [style.color]="red"
  • ng-class="name" => [class.name]
  • ng-class={'name': condition} => [class.name]="condition"

Built-in Directives

For


        import {bootstrap, Component, View, For} from 'angular2/angular2';

        @View({
          templateUrl: 'todos.html’,
          directives: [For]
        })
        class TodoApp{
          constructor() {
            this.todos = [‘first thing’, ‘second thing’, ‘third thing’];
          }
        }
      

*for="#item of items"


        <ul *for=“#todo of todos”>
          <li>
            <p>{{todo}}</p>
          </li>
        </ul>
      

ng-repeat="todo in vm.todos"

index


      <ul *for=“#todo of todos; var i = index;”>
        <li>
          <p>{{i}}. {{todo}}</p>
        </li>
      </ul>
    

ng-repeat="todo in vm.todos track by $index">

If


        import {bootstrap, Component, View, For, If} from 'angular2/angular2';

        @View({
          templateUrl: 'todos.html’,
          directives: [For, If]
        })
        Class TodoApp{}
      

*if="condition"


        <ul *for=“#todo of todos; var i = index;”>
          <li>
            <p>{{index}}. {{todo.title}}</p>
          </li>
          <form *if="isEdit(i)">
            <p (dblclick)="doneEditing(todo)">Edit me!</p>
          </form>
        </ul>
      

ng-if="vm.currentIndex === $index">

Angular 2 Forms

Control


        import {Control, FormDirectives, ControlDirective} from 'angular2/forms';

        @Component({ ... })
        @View({ ...
          directives: [For, If, FormDirectives]
        })
        class TodoApp {
          constructor( ...) {
          ...
            this.newTodo = new Control('');
          }
        }
      

Control


        <input [control]="newTodo" (keydown)="addTodo($event)">
      

ng-model

Validators


        import {CustomValidators} from 'validators';

        @Component({
          injectables: [TodoStorage, CustomValidators]
        })
        class TodoApp{
          constructor(storage: TodoStorage, custom: CustomValidators) {
            this.newTodo = new Control('', custom.badLanguage);
          }
        }
      

Custom Validators


        export class CustomValidators{
          // c: Control
          badLanguage(c) {
            // 18dogbaby = bad language in Korean
            if(c.value.match(/18dogbaby/)) {
              return {
                badLanguage: true
              };
            }
          // return null = valid
          return null;
          }
        }
      

Validators


        <form id="todo-form" [class.invalid]="!newTodo.valid">
      

Valid, Pristine, Dirty



Complex Forms:

ControlGroup | FormBuilder

NG2Ch llenges


Challenge

Demo

Setup

Help

Solutions



        self rating: ★★★☆☆
        link
        version
        data & @name
        comments
      

NG2Ch llenges


Beginner

High Beginner

Intermediate

Credits

Shawn McKay | Blog | Github |