Last active
October 16, 2019 19:13
-
-
Save dmorosinotto/c74f2c0d2e4cef4790815ec3b0684cc7 to your computer and use it in GitHub Desktop.
Angular call-apply Pipe Solve Perf Problem of calling function inside template/interpolate -> sample: https://stackblitz.com/edit/angular-call-aply-pipe
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 { Pipe, PipeTransform } from '@angular/core'; | |
const error_this = function(){ console.error("DON'T USE this INSIDE A FUNCTION CALLED BY | call OR | apply IT MUST BE A PURE FUNCTION!"); return false; } | |
const NOTHIS = !('Proxy' in window) | |
? Object.seal({}) | |
: new Proxy({}, { | |
get: error_this, | |
set: error_this, | |
deleteProperty: error_this, | |
has: error_this, | |
}); | |
@Pipe({ | |
name: 'call', | |
pure: true | |
}) | |
export class CallPipe implements PipeTransform { | |
transform(value: any, args?: Function): any { | |
return args.call(NOTHIS,value); | |
} | |
} | |
@Pipe({ | |
name: 'apply', | |
pure: true | |
}) | |
export class ApplyPipe implements PipeTransform { | |
transform(fn: Function, ...args: any[]): any { | |
return fn.apply(NOTHIS, args); | |
} | |
} |
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
<hello name="{{ name }}"></hello> | |
<p> | |
Start editing to see some magic happen :) | |
</p> | |
<article> | |
<header>TEST PIPE | call </header> | |
<aside> | |
SOMETHING {{ name | call: doSomething }}<br/> | |
SOMETHING OBJ {{ obj.x | call: doSomething }}<br/> | |
</aside> | |
</article> | |
<article> | |
<header>TEST PIPE | apply</header> | |
<aside> | |
DOAPPLY {{ doParams | apply : name : obj : obj.x }}<br/> | |
DOAPPLY OBJ {{ doParams | apply: obj }}<br/> | |
</aside> | |
</article> | |
<article> | |
<header>PERF PROBLEM | |
<p><b>Calling function in interpolation -> run on EVERY CHANGE DETECTION CYCLE!!!</b> | |
<i> Even if you Change X or Y that is not used in doSomething(name,...)!!!</i></p> | |
</header> | |
RENDER ALWAYS -> {{ doSomething(name, 'EVERY change detention') }} | |
<!-- SOME WAY THAT CAUSE CHANGE DETENCION --> | |
<div> | |
<button (click)="nochange()">NO CHANGE</button> | |
<input [(ngModel)]="name"> | |
<button (click)="change('x')">CHANGE x</button> | |
<button (click)="change('y')">CHANGE y</button> | |
<button (click)="changeref()">CHANGE REF</button> | |
</div> | |
</article> |
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 '@angular/core'; | |
@Component({ | |
selector: 'my-app', | |
templateUrl: './test.component.html', | |
styleUrls: [ './test.component.css' ] | |
}) | |
export class AppComponent { | |
name = 'Angular'; | |
obj:any; | |
constructor(){ | |
this.obj = {x:'x', y:'y'} | |
} | |
doSomething(x, where) { | |
console.log("SOMTHING", x, where); | |
//DO SOMETHING WITH X | |
//this.name = "CIAO"; | |
return x; | |
} | |
doParams(...args) { | |
console.warn("PARAMS", ...args); | |
return JSON.stringify(args); | |
} | |
nochange() { | |
console.log("NO CHANGE"); | |
} | |
change(fld: string) { | |
console.log("CHANGE",fld); | |
this.obj[fld] = new Date(); | |
} | |
changeref() { | |
this.obj = {x:'1', y:'2'} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment