Last active
March 31, 2016 00:08
-
-
Save alvipeo/36de30bdccd126063344 to your computer and use it in GitHub Desktop.
Change detection OnPush
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
System.config({ | |
//use typescript for compilation | |
transpiler: 'typescript', | |
//typescript compiler options | |
typescriptOptions: { | |
emitDecoratorMetadata: true | |
}, | |
//map tells the System loader where to look for things | |
map: { | |
app: './src' | |
}, | |
//packages defines our app package | |
packages: { | |
app: { | |
main: './main.ts', | |
upload: './upload.ts', | |
typingText: './typingText.ts', | |
defaultExtension: 'ts' | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>playground</title> | |
<link rel="stylesheet" href="styles.css"> | |
<script src="https://code.angularjs.org/2.0.0-beta.12/angular2-polyfills.js"></script> | |
<script src="https://code.angularjs.org/tools/system.js"></script> | |
<script src="https://code.angularjs.org/tools/typescript.js"></script> | |
<script src="config.js"></script> | |
<script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.4/dist/global/Rx.js"></script> | |
<script src="https://code.angularjs.org/2.0.0-beta.12/angular2.dev.js"></script> | |
<script src="https://code.angularjs.org/2.0.0-beta.12/http.dev.js"></script> | |
<script src="https://code.angularjs.org/2.0.0-beta.12/router.dev.js"></script> | |
<script> | |
System.import('app') | |
.catch(console.error.bind(console)); | |
</script> | |
</head> | |
<body> | |
<app></app> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Component} from 'angular2/core'; | |
import {bootstrap} from 'angular2/platform/browser'; | |
import {Observable} from 'rxjs/Rx'; | |
import {IlgUploader} from "./upload"; | |
@Component({ | |
selector: 'app', | |
template: `<div> | |
<ol><li>Click on select files</li><li>Select file (upload not implemented)</li><li>Click start</li><li>You'll see an Error message below</li></ol> | |
<hr/> | |
<ilg-uploader></ilg-uploader> | |
<hr/> | |
<p>When a user starts uploading files, every one of them will have a progress (uploading state). This should be reflected on a view. But since OnPush, is it the only possible method - to use ChangeDetectorRef and its markForCheck() method?</p> | |
<p>I know OnPush means CD kicks in only when @Input() props change. But what if changing @Input() prop starts a whole new internal (to component) process with its state changes which, in turn, should be reflected on a view?</p> | |
<p>What's interesting is why TypingText works without using ChangeDetectorRef and Upload doesn't? Just because TypingText.showError$ is an Observable and Upload.errorText is not?</p> | |
<p>What's the best of doing this really?</p> | |
</div>`, | |
directives: [IlgUploader] | |
}) | |
export class App { | |
constructor() {} | |
} | |
bootstrap(App, []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Input, Component, ChangeDetectionStrategy, ChangeDetectorRef, AfterViewInit, OnChanges, SimpleChange} from "angular2/core"; | |
import {Observable} from 'rxjs/Rx'; | |
@Component({ | |
selector: "ilg-flying-text", | |
template: "{{ showError$ | async }}", | |
changeDetection: ChangeDetectionStrategy.OnPush | |
}) | |
export class IlgFlyingText implements AfterViewInit, OnChanges { | |
@Input() text: string; | |
showError$: Observable<string>; | |
ngAfterViewInit() { | |
this.initObservable(); | |
} | |
ngOnChanges(changes: { [propName: string]: SimpleChange }) { | |
this.initObservable(); | |
} | |
private initObservable() { | |
if (!!this.text) { | |
console.log(this.text); | |
this.showError$ = this.createErrorObservable(this.text); | |
} else { | |
this.showError$ = Observable.of(null); | |
} | |
} | |
private createErrorObservable(errText: string): Observable<string> { | |
//console.log(err); | |
let o1$ = Observable.from(errText); | |
let o2$ = Observable.interval(25); | |
//let o3$ = o1$.flatMap(v => v); | |
//console.log(o3$); | |
let o$ = o1$.zip(o2$) | |
.map(tuple => tuple[0]) | |
.scan((acc, val) => acc += val[0]); | |
//.do(val => console.log(val)); | |
return o$; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Input, Component, ChangeDetectionStrategy, ChangeDetectorRef, AfterViewInit, OnChanges, SimpleChange, ViewChild} from "angular2/core"; | |
import { CORE_DIRECTIVES, FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, Control } from 'angular2/common'; | |
import {IlgFlyingText} from './typingText'; | |
@Component({ | |
selector: "ilg-uploader", | |
template: `<div> | |
<p>Drag files to any place here or ...</p> | |
<a href="#" (click)="onSelectFilesBtnClick($event)">Select files to Upload</a> | |
<form [ngFormModel]="frmUpload"> | |
<input #fileInput type="file" (change)="onFilesChanged($event)" multiple accept="image/*" [ngFormControl]="filesInput" hidden /> | |
<div *ngIf="selectedFiles"> | |
<ul> | |
<li *ngFor="#file of selectedFiles">{{file.name}}</li> | |
</ul> | |
<button type="button" (click)="onStartUpload()">Start</button> | |
</div> | |
</form> | |
</div> | |
<div class="alert alert-danger" *ngIf="errorText"> | |
<strong>Error!</strong> <ilg-flying-text [text]="errorText"></ilg-flying-text> | |
</div>`, | |
changeDetection: ChangeDetectionStrategy.OnPush, | |
directives: [CORE_DIRECTIVES, IlgFlyingText], | |
}) | |
export class IlgUploader { | |
@ViewChild("fileInput") fileInput: any; | |
private selectedFiles: []; | |
private errorText: string; | |
constructor(private cd: ChangeDetectorRef, private fb: FormBuilder) { | |
this.frmUpload = fb.group({ | |
"filesInput": ["", Validators.required] | |
}); | |
this.filesInput = this.frmUpload.controls["filesInput"] as Control; | |
} | |
onSelectFilesBtnClick($event: any) { | |
$event.preventDefault(); | |
this.fileInput.nativeElement.click(); | |
} | |
onFilesChanged($event: any) { | |
this.clearError(); | |
this.selectedFiles = []; | |
for (let i = 0; i < $event.target.files.length; i++) { | |
const file: File = $event.target.files[i]; | |
this.selectedFiles.push({name: file.name}); | |
} | |
} | |
onStartUpload() { | |
this.clearError(); | |
// suppose we get an error here | |
this.errorText = "Something bad happened!"; | |
} | |
private clearError() { | |
this.errorText = null; | |
this.cd.markForCheck(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* todo: add styles */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment