angular2 changedetection - Angular 2 click event callback without triggering change detection -
i'm having major trouble trying perform logic inside (click)
event callback function in angular 2 without triggering change detection.
why don't want trigger change detection
the callback function performs simple animated scroll top. effects no other components , therefore don't need change detection fire in every component, in fact don't want fire! because change detection fire in every component, performance of animation on mobile extremely poor.
what i've tried
i know can run code outside of zone using
this._zone.runoutsideangular(() => { somefunction(); })
this works nicely when code want run outside zone isn't invoked click
, keyup
, keydown
event etc.
because component looks like...
<button (click)="dothing()">do thing outside zone!</button>
dothing() { this._zone.runoutsideangular(() => { myfunction(); }) }
...myfunction
run outside zone click
event trigger change detection.
i've implemented onpush
change detection strategy in many of components possible.
it's important change detection not triggered here can't find way prevent it.
edit see plnk change detection set onpush
in components. clicking subrow component button triggers cd in subrow, row , app components.
as noted, setting component in click
event occurs onpush
still result in change detection being triggered.
out-of-the-box event handling
@component({ selector: 'test' template: `<button (click)="onclick($event)">click me</button>`, changedetection: changedetectionstrategy.onpush }) export class mycomponent { onclick(e:event) { e.preventdefault(); e.stoppropagation(); this._zone.runoutsideangular(() => { // gets run outside of angular parent function still triggers change detection }); return false; /* * change detection triggered * regardless of happens above */ } }
most of time may not problem when rendering , painting performance functions essential i'm taking approach of entirely by-passing angular's built-in event handling. own experiments following seems easiest , maintainable way approach this.
by-pass out-of-the-box event handling
the idea here use rxjs manually bind whatever events want, in case click, using observable.fromevent
. example demonstrates practice of cleaning event subscriptions.
import {component, elementref, oninit, ondestroy, ngzone} '@angular/core'; import {observable} 'rxjs/observable'; import {subscription} 'rxjs/subscription'; @component({ selector: 'test' template: `<button #mybutton>click me</button>`, changedetection: changedetectionstrategy.onpush }) export class mycomponent implements oninit { private _subs:subscription[] = []; // reference template variable @viewchild('mybutton') mybutton:elementref; constructor(private _zone:ngzone){} ngoninit() { this.manuallybindtoviewevents(); } manuallybindtoviewevents() { this.subscribetomybutton() } subscribetomybutton() { let sub:subscription; this._zone.runoutsideangular(() => { sub = observable.fromevent(this.mybutton.nativeelement, 'click').subscribe(e => { console.log('yayyyyy! no change detection!'); }) }); this._subs.push(sub); } ngondestroy() { // clean subscriptions this._subs.foreach(sub => sub.unsubscribe()); } }
hopefully others in similar situation.
change detection is really good for angular.
ReplyDeleteAngularjs Training in Bangalore , Angular 2 Training in bangalore , Python Training in Bangalore