Intro to Angular

Angular vs AngularJS

What's the same

  •  Dom binding {{ text }}
  •  NOTHING!!!

How to create a component

@Component({
  templateUrl: './some-html.pug',
  styleUrls: ['./somecss.scss']
})
class MyComponent {

}

@Component({
  template: `
    <span>Hello {{ text }}</span>
  `,
  styles: ['h1 {font-weight: normal;}']
})
class HelloComponent {
  text: 'World'
}

No Digest!!

How do things run?

- Events (click, submit)

- XHR

- Timers (setInterval, setTimeout)

Zone Events

Zone Events

Zones provide hooks for events

zone
  .fork({onEnter: doStuff, onLeave: doStuff})
  .run(task)

Monkey patched setTimeout/setInterval/Observables

notify change detectors

Change Detectors

Every component has it's own change detector

Update Behaviors

Always starts from root

Mutable vs Immutable

val1 === val2??

var mutable = {}
var oldValue = mutable
var newValue = Object.assign(mutable, {hi: 1})

oldValue === newValue // true but property changed so we now much check every value
var immutable = Immutable.from({})
var oldValue = immutable
var newValue = immutable.hi = 'test'

oldValue === newValue // false no property checks needed

Removing useless checks

ChangeDetectorStrategy.OnPush

@Component({
  templateUrl: './some-html.pug',
  styleUrls: ['./somecss.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
class MyComponent {

}

Further Reduction Of CD 

@Component() // assuming OnPush
class CartBadgeCmp {

  @Input() addItemStream:Observable<any>;
  counter = 0;



  ngOnInit() {
    this.addItemStream.subscribe(() => {
      this.counter++;

    })
  }
}

Binding Syntax

<ng-container '*ngIf'='isShowing'>
  <my-component [props]='myProps' [(model)]='myModel'></my-component>

  <button (submit)='onSubmit($event)'></button>
</ng-container>

Adding in external libraries

Rare you need to do this

this._ngZone.runOutsideAngular(() => {
  // do stuff with lib that isn't updating change detection
})
@Component(...)
class MyComp {
  constructor(ref: ChangeDetectorRef) {
    someExternalLibraryOnUpdate(() => ref.markForCheck())
  }
}

Reactive Forms

form('(ngSubmit)'='onSubmit() '[formGroup]'='userFormGroup')
  .form-group
    label Name
    input(formControlName='name' type='name')

  .form-group
    label Email
    input(formControlName='email' type='email')
  
  .form-group
   label Referrals
   input(
     '*ngFor'='let control of userFromGroup.get('refferals').controls; let i = index' 
     '[formControl]'='control'
   )

  button('(click)'='addControl()') Add
  button('(click)'='refferals.removeAt(i)') Remove
  
@Component(...)
class MyComponent {
  public referrals = new FormArray([
    new FormControl()
  ])

  public userFormGroup = new FormGroup({
    name: new FormControl('', Validators.required),
    email: new FormControl('', [Validators.required, myEmailvalidator]),
    referrals: this.referrals
  })

  addControl() {
    this.referrals.push(new FormControl())
  }
}

Useful Template Shortcuts

// ng-if-else
ng-template(#loading) Loading...

div('*ngIf'='userObservable | async; else loading; let user'>
  | {{ user.name }}
// Observables in templates
@Component({
  template: 'span {{ userName | async }}'
})
class MyComp {
  userName: Observable<string>
}

Lastly - AoT Compilation

var currVal_6 = this.context.newName;
if (import4.checkBinding(throwOnChange, this._expr_6, currVal_6)) {
    this._NgModel_5_5.model = currVal_6;
    if ((changes === null)) {
        (changes = {});
    }
    changes['model'] = new import7.SimpleChange(this._expr_6, currVal_6);
    this._expr_6 = currVal_6;
}
this.detectContentChildrenChanges(throwOnChange);

Further Reading

http://blog.mgechev.com/2016/08/14/ahead-of-time-compilation-angular-offline-precompilation/

https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

RTFM

deck

By Mika Kalathil

deck

  • 793