angular 2: concat arrays in a pipe without loosing databinding

流过昼夜 提交于 2019-12-11 01:34:19

问题


I have a simple pipe:

export class MergePipe implements PipeTransform {
transform(first: any[], second: any[], order: Boolean): any {
    return order ? first.concat(second):second.concat(first);
}

Which I'm using on a simple button: <button *ngFor="let item of items | sort:suffix | filter:filterargs | merge:newItems:false"></button>.

And then push some values into the newItems with newItems.push(values) but nothing happens. If I remove the pipe from *ngFor, I receive the expected changes.

I think I missunderstand something on how the databinding is working.

Thanks for any helpful information.


回答1:


If you modify one of the arrays, Angulars change detection won't see the change and therefore won't call the pipes.
Angular change detection only checks object identity, but not object content.

You can make the pipe impure, or you can create a copy of the pipe after each modification for Angular to see a new array.

@Pipe({ name: '...', pure: false})

This can cause severe performance issues, because now the pipe is called every time change detection is run.

someMethod() {
  this.newItems.push(someNewItem);
  this.newItems = this.newItems.slice();
}

Creating a copy after modification causes Angular change detection to recognize the change and call the pipes.

Yet another way is to use a dummy parameter;

counter:int = 0;
someMethod() {
  this.newItems.push(someNewItem);
  this.counter++;
}
<button *ngFor="let item of items | sort:suffix | filter:filterargs | merge:newItems:false:counter"></button>

This way change detection will detect the change of a parameter and call the pipes.




回答2:


It seems like Angular would not know to re-evaluate that pipe if the array reference didn't change.

If we look at their discussion of pipes:

You add the hero into the heroes array. The reference to the array hasn't changed. It's the same array. That's all Angular cares about. From its perspective, same array, no change, no display update.

https://angular.io/docs/ts/latest/guide/pipes.html

You should put this code instead:

newItems = newItems.concat(values)

Which will update the reference and cause the pipe to be re-evaluated.



来源:https://stackoverflow.com/questions/43873439/angular-2-concat-arrays-in-a-pipe-without-loosing-databinding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!