2017-09-01 4 views
0

不変モデルオブジェクトの配列を使用しているときにCSSトランジションを実行できませんでした。角度:ngFor内の不変モデルのアニメーション

angleは、これらが機能するためにプロパティのインプレース更新が必要ですか、何か間違っていますか?一例として、

:ここでは( https://plnkr.co/edit/PBSPtk9vMig7cxnHoJqA

export class Box { 
    constructor(public selected:boolean){ 
    } 
} 

function toggle(box:Box):Box{ 
    return new Box(!box.selected) 
} 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <ul> 
    <li *ngFor="let box of boxes"> 
    <div 
    style="display:inline-block; width: 20px; height:20px; transition: 1s; margin:5px; cursor:pointer;" 
    [ngStyle]="{'background': box.selected?'green':'red'}" 
    > </div> 
    <button (click)="toggle_in_place(box)">toggle (in-place)</button> 
    <button (click)="toggle_replace_box(box)">toggle (replace box)</button> 
    <button (click)="toggle_replace_array(box)">toggle (replace array)</button> 
    </li> 
    </ul> 
    `, 
}) 
export class App { 

    boxes: Box[]; 

    constructor() { 
    this.boxes = [new Box(true), new Box(false), new Box(true)]; 
    } 

    toggle_in_place(box:Box){ 
    box.selected=!box.selected; 
    } 

    toggle_replace_box(box:Box){ 
    const index = this.boxes.indexOf(box); 
    this.boxes[index]=toggle(box); 
    } 

    toggle_replace_array(box:Box){ 
    this.boxes = this.boxes.map(v=>v===box?toggle(v):v); 
    } 
} 

私はを通じてdiv要素の色をアニメーション化しようとしている

[ngStyle]="{'background': box.selected?'green':'red'}" 

によって更新することができますbox.selected:

  • プロパティをインプレースで変更する(toggle_in_place)、
  • 'ボックス'モデル(toggle_replace_box)を置き換えます。
  • アレイ全体(toggle_replace_array)を置き換えます。

しかし、toggle_in_placeは目に見える遷移につながる唯一のものです。

これはちょうど私が住んでいなければならないものですか?

答えて

0

ここで起こっていること:配列が変更されると、ngForは新しい配列のオブジェクト参照を古いものと比較し、変更された要素を再描画してCSS遷移を破棄します。

これを解決するために、ngForには参照比較の代わりに使用されるトラッキング関数を与えることができます。 IDなく、オブジェクト参照を使用するようにトラッキング機能を指定し、固定するために

trackingFunction(index:number, box:Box){ 
    return box.id; 
} 

有するngForは、それを使用する:

<li *ngFor="let box of boxes;trackBy:trackingFunction"> 

例: https://plnkr.co/edit/4OXemdSf1Hsm1NU6ZhzT

0

私はそれがあなたと一緒に暮らさなければならないものだと思います。後者の2つのケースでは、毎回ボックスの新しいインスタンスを作成しているので、そこから移行するものはありません。

おそらく、基本的にはボックスの周りのラッパーで、コンストラクターに「トランジション」ブール値を渡すことができます。しかし、回避策はユースケースにかなり依存しています。

+0

遷移shouldn」をボックスインスタンスについて気にすると、結果として生じるDOM変更だけが表示されます。 何が起こっているのかは、スタイルを更新するのではなく、何らかの理由でdivインスタンス全体が置き換えられるというボックスインスタンスの変更だと仮定します。 おそらくそれがngForの内部にあるからでしょうか? – Murray

+0

あなたはその権利を持っています。 Angularは、新しいボックスが返されてから既存のものを更新するのではなく、新しいインスタンスでDOMを再構築しています。 – Adam