I have an array a
containing 50,000+ objects and I have a pipe which takes this array a
and transforms this into some output which is then displayed in the view.
The pipe is pure meaning that only when the reference to array a
changes will it re-evaluate.
I have a method modifyArray
which adds/removes some elements from array a
. When completed I would like the pipe to be re-evaluated so that the view re-renders.
Because of the way that Angular enforces immutability, the only option I have for the pipe to be re-evaluated is for the method modifyArray
to return a copy of array a
with the changes applied, so that Angular can detect that the reference has changed and trigger the pipe, something like this:
modifyArray(a: T[]): T[] {
a.push(b);
a.slice(c);
return [...a];
}
However for such an array with 50,000+ elements, there is a real performance degradation when making a copy of the array.
I would have expected that explicitly triggering change detection after invocation of this method, for example by calling ApplicationRef.tick()
or ChangeDetectorRef.detectChanges()
, would allow Angular to figure out that the array has been modified, but this is not the case:
this.a = modifyArray(a);
this.applicationRef.tick();
Making a copy of the array is not an option as the data set is too large. Making the pipe not pure is also not an option as the transformation the pipe applies to the input is expensive.
Does anyone have any ideas on how this can be achieved?
Impure pipes in angular are the pipes that execute when it detects an impure change in the input value. An impure change is when the change detection cycle detects a change to composite objects, such as adding an element to the existing array.
By default, pipes are defined as pure so that Angular executes the pipe only when it detects a pure change to the input value. A pure change is either a change to a primitive input value (such as String , Number , Boolean , or Symbol ), or a changed object reference (such as Date , Array , Function , or Object ).
A pure pipe is only called when Angular detects a change in the value or the parameters passed to a pipe. An impure pipe is called for every change detection cycle no matter whether the value or parameter(s) changes. This is relevant for changes that are not detected by Angular.
Angular2 change detection only checks object references. It doesn't depend how often it checks but only that it doesn't look inside arrays ;-), this is why explicitly invoke change detection doesn't have any effect.
Perhaps doing change detection yourself in ngDoCheck
with an IterableDiffer
might help in your case but your question doesn't provide enought information to know for sure.
You can use the *ngFor
directive as example https://github.com/angular/angular/blob/14ee75924b6ae770115f7f260d720efa8bfb576a/modules/%40angular/common/src/directives/ng_for.ts#L122
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With