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.


Comments

Post a Comment

Popular posts from this blog

elasticsearch python client - work with many nodes - how to work with sniffer -

unity3d - Rotate an object to face an opposite direction -

angular - Is it possible to get native element for formControl? -