2017-07-25 21 views
2

を塗り替え、私は奇妙な行動を参照してください。角度変化検出プロセスは、私は角度変化検出処理について学習し、私のChromeでのdevのツールをチェックしていDOM

動作を実証するための私のplnkr:私は追加単純な要求をシミュレートする

constructor() { 
    this.list = [{name: 'Gustavo'}, {name: 'Costa'}] 

<li *ngFor="let item of list">{{item.name}}</li> 

とコンストラクタ:http://plnkr.co/edit/cTLF00nQdhVmkHYc8IOu

私は、ビューとの単純なコンポーネントを持っています。

// simulating request repaint the DOM 
setInterval(() => { 
    this.list = [{name: 'Gustavo'}, {name: 'Costa'}]; 
}, 2000); 

あなたが気づいた場合は、配列listが初期値に等しいリストを受け取ります。

if(oldName !== name) { // ('Gustavo' !== 'Gustavo') 
// update the view 
} 

しかし、値が同じである、2秒ごとの再描画THE DOM 理由角度:変化検出処理のビュー内の値は、我々はこのようなコードを持っている場合アンギュラチェックのは、想像してみましょうか。?

しかし場合、私は、オブジェクトを変異させ、再描画は、あなたが上記のplnkrリンクでこれをテストすることができ

// simulating request there is not repaint 
setInterval(() => { 
    this.list[0].name = "Gustavo"; // no repaint because it's the same value 
    this.list[1].name = "Costa 2"; // repaint 
}, 2000); 

を発生しません。

答えて

5

です。

const trackByIdentity = (index: number, item: any) => item; 

明らかに新しい配列を作成すると、新しいオブジェクト参照が作成され、角度によって変更が検出されます。あなたは配列参照を変更しなかった場合でも、オブジェクト参照が変化するため、角度はまだアイテムが変更されていると思います:

setInterval(() => { 
    this.list.length = 0; 
    this.list.push({name: 'Gustavo'}); 
    this.list.push({name: 'Costa'}); 
}, 2000); 

あなたがオブジェクト名で追跡するために、カスタムtrackByFunctionをご提供することができます

@Component({ 
    selector: 'my-app', 
    template: ` 
    <li *ngFor="let item of list; trackBy:identify">{{item.name}}</li> 
    ` 
}) 
export class App { 
    list:[]; 

    identify(index, item){ 
    return item.name; 
    } 

この方法でDOMは更新されません。 this plunkerを参照してください。

あなたは約ngForであるので、this answerを読むことができます。ngForがどのようにフードで動作するかを説明しています。

+0

これは私が知りませんでした、ありがとう:) – 0mpurdy

+0

@ 0mpurdy、 、アップヴォートのおかげで) –

+0

ちょっとマキシムス、もう一度ありがとう! AngularJS開発者の場合、 '$$ hashKey'はオブジェクトの角度をAngular? trackBy AngularはAngularJSと同じ考えですか? (この記事でAngularの同じ概念が適用されますか? http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/)? –

1

参照が変更されたため、角度と角度が更新されるたびに新しいアレイが作成されているためです。あなたは同じ参照に割り当てた場合は、この2秒ごとに

otherList = [{name: 'Gustavo'}, {name: 'Costa'}]; 

constructor() { 
    this.list = [{name: 'Gustavo'}, {name: 'Costa'}] 
    setInterval(() => { 
    this.list = this.otherList; 
    }, 2000);  
} 

Updated plunker

+0

あなたがそれを同じ参照に割り当てても変更はありません)角度は更新されませんDOM –

+0

@ Maximusこれは彼が求めていることだと思いますか?なぜアレイが変化しないのであれば、角は依然として検出を変化させるのですか?A:これは参照によるものですか? – 0mpurdy

+0

いいえ、彼はなぜ配列参照をうまく動かすとDOMのudpateがトリガーされているのかを問い合わせています –

1

は@ 0mpurdyに追加する場合ではありません、Objectsは(とそうArraysを行う)、彼らが持っている場合でも、同じことはありません一方が別のものの参照であるか、または両方が同じ参照を共有している場合を除いて、同じプロパティと値。彼らはない参照することにより、値で比較している原因

プリミティブは、他の一方で、他のプリミティブに等しくすることができます。そこには、同じ値のため、手動で値を上書きする場合、検出がトリガ変化なしませんが、あなたはオブジェクトが明らかに等しい場合でも、全部を交換する場合、変化検出をトリガを取得しようとしている理由です。角度がアイデンティティによってアイテムを追跡するDefaultIterableDifferのデフォルトtrackByFunctionを使用しているため

関連する問題