1

I have a fairly big list of data and every element has a filter applied. For performance reasons (I want to add a lot of attributes to each entry) I only want to update the list when data changes (it's fine if updating it is unperformant). Unfortunately, the OnPush ChangeStrategy in Angular 2 still updates whenever I click on something.

Is there a way to ONLY manually trigger updates/checks (using for example changeDetectorRef.markForCheck())and not have it automatic on every click event?

Both AngularJS (1.5) and Angular 2 are fine.

5
  • Change detection in Angular2 is vastly more efficient than in AngularJS1.x. Are you certain it won't meet your needs with an OnPush ChangeStrategy? Commented Mar 26, 2016 at 2:43
  • See this answer Commented Mar 26, 2016 at 2:53
  • @EricMartinez I saw that post before, but the problem is, that only triggers an ADDITIONAL change detection. However, I want to get rid of all the unnecessary change detections. In my case I have a pure pipe which always triggers when the change detection triggers. Commented Mar 26, 2016 at 2:55
  • Try detach(), and manually adding any click handlers in afterViewInit() using runOutsideAngular() and addEventListener() -- i.e., don't use (click) in your template. Call detectChanges() when you want to manually run changed detection. I have no idea if this will work. Commented Mar 26, 2016 at 4:17
  • @MarkRajcok it seems like it's not possible to call detectChanges() with a detached changeDetector. Now I tried a reattach + detach which seems to work but does everything twice (even in prod mode). Commented Mar 26, 2016 at 7:53

1 Answer 1

1

This should work (at least it does in this Plunker):

@Component({
  selector: 'manual',
  template: `<br>manual: {{_counter.obj.counter}}
  <br><button (click)="0">click me</button>
    <li *ngFor="#item of items">{{item}}</li>`,
})
export class Manual {
  items = 'one two'.split(' ');
  constructor(private ref: ChangeDetectorRef, private _counter:Counter) {}
  ngOnInit() {
     this.ref.detach();
     setInterval(_ => {
        this.items.push(`CD ran when counter=${this._counter.obj.counter}`);
        this.ref.reattach();
        this.ref.detectChanges();
        this.ref.detach();
     }, 3000);
  }
}

In the plunker I have a Counter service that updates obj.counter every second. In the Manual component, {{_counter.obj.counter}} (hence the view) only updates when detectChanges() is called – every 3 seconds. Clicking the click me button does not cause the view to update, as desired.

I did not specify OnPush. However, if you do, it does not seem to alter the desired operation.

In the plunker I also have an Automatic component, and its {{_counter.obj.counter}} (hence its view) updates every second, as expected.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.