2017-05-09 29 views
2

データバインディング失うことなく、パイプで連結アレイ:角度2:私は、単純なパイプを持っている

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

アレイの1つを変更すると、角度変更の検出で変更が表示されず、パイプが呼び出されません。
角度変化の検出は、オブジェクトのアイデンティティのみをチェックし、オブジェクトの内容はチェックしません。

パイプを不純にすることもできますし、角度を変更するたびにパイプのコピーを作成して、新しい配列を表示することもできます。

@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

ありがとう、完璧な答え特に2番目のソリューションは素晴らしい回避策です。 – 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)

を再評価されるべきパイプ。

関連する問題