Angular vs AngularJS
What's the same
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