简体   繁体   中英

How to create new reference to existing array without copying the array

Is it possible to create a new reference to an array without going through the array? My problem is that I have a pure angular pipe which doesn't detect push/pop changes. I would like to avoid solutions like this:

this.array = this.array.filter(e=>true)

Which adds complexity just to update reference. I have tried first thing that came to my head but it doesn't work (pipe doesn't detect any changes) and I am not familiar with js/ts enough to know why it didn't work.

const newRef = this.array;
this.array = null;
this.array = newRef

I have pipe which gets array of objects and array of filters and returns array of filtered objects.

@Pipe({
  name: 'eventFilter'
})
export class EventFilterPipe implements PipeTransform {

  transform(events: EventDtos[], filters:Filter[]): any {
     //return filtered events
  }

Pipe useage:

<div  class="event" *ngFor="let event of events  | eventFilter:filters">
   html stuff
</div>

After pushing/poping filter from filters , pipe's transform isn't called so I am using this code to force transform call:

this.filters = this.filters.filter(e=>true)

But at this point I don't know which one is faster, this method or impure pipe. So Ideally I would like to leave pure pipe and update filters reference without adding complexity

Are you probably looking for a impure pipe in Angular? In this way, your pipe is automatically update for every input changes. You can find more information on the official guide https://angular.io/guide/pipes#pure-and-impure-pipes

I don't recommend you to use impure pipe, it will be executed and filter events on every change detection, and there may be hundreds of change detections per second.

What about your attempt of the reference changing, actually it doesn't change the reference, you just change a variable, which contains the reference:

const newRef = this.array; // newRef references the array
this.array = null;
this.array = newRef // this.array references the same array, nothing is changed

So, copying of the array, as you did, is better solution, but there are simpler ways:

this.array = [...this.array];
// or
this.array = this.array.slice();

Another solution is to use a Subject and AsyncPipe . In this case there is no need to copy the array. If the array is big, or filters are often changed, it may be the preferred way:

@Component({...})
class MyComponent {
    readonly filters$ = new BehaviourValue<Filter>([]);

    ...
    addFilter(filter: Filter): void {
        this.filters$.value.push(filter);
        this.filters$.next(this.filters$.value);
    }
}
<div  class="event" *ngFor="let event of events | eventFilter:(filters$ | async)">
   html stuff
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM