2017-05-09 46 views
2

我有一个简单管:角2:在管道中的concat阵列而不丢失数据绑定

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

我使用一个简单的按钮,其中:<button *ngFor="let item of items | sort:suffix | filter:filterargs | merge:newItems:false"></button>

然后用newItems.push(值)将一些值推入newItems,但没有任何反应。如果我从* ngFor中删除管道,我会收到预期的更改。

我想我对数据绑定的工作方式有些误解。

感谢您提供任何有用的信息。

+0

纯管道只在更改'指针'时更新,例如你的'第一个'换成另一个数组,而不能自己改变。你可以通过设置@Pipp({pure:false})来改变不纯的管道。您可以搜索管道文件。 –

+0

感谢您的回答。用不纯的管子可以正常工作,但是现在还不能真正理解它是如何工作的。 – Draftsman

回答

3

如果修改其中一个数组,Angulars更改检测将不会看到更改,因此不会调用管道。
角度更改检测仅检查对象标识,但不检查对象内容。

您可以使管道不纯,或者您可以在每次修改后为Angular创建一个管道副本以查看新阵列。

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

这会导致严重的性能问题,因为现在每次运行更改检测时都会调用管道。

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

修改后创建副本会导致角度更改检测识别更改并调用管道。

另一种方法是使用虚拟参数;

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> 

这样变化检测将检测参数的变化,并调用管道。

+0

非常感谢你,完美的回答,特别是第二个解决方案是一个很好的解决方法。 – Draftsman

+0

不客气。很高兴听到它适合你:) –

0

看起来像Angular不知道如果数组引用没有改变重新评估管道。

如果我们看一下他们的管道的讨论:

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

你应该把这个代码,而不是:

newItems = newItems.concat(values)

将更新的参考和原因管道将被重新评估。