2017-10-16 3 views
1

私は、そのアイテムの1つをクリックで選択する必要がある単純なリストを持っています。ただし、x秒ごとにリストが更新され、選択内容が失われているように見えます。配列が更新されている間に* ngForでクラスを保持する方法は?

新しく作成した要素に選択範囲を追加するには、setTimeoutを導入しましたが、「点滅」効果があるようです。

setInterval(() => { 
    this.locations.forEach((o, i, a) => a[i] = a[i] + 's'); // update locations 

    setTimeout(() => { 
    if (this.selectedLocationID) document.getElementById(this.selectedLocationID).classList.add('selectedLocation'); 
    }, 0); 

}, 1000); 

plunkのように「点滅」を防止するにはどうすればよいですか?

答えて

1

これが実行されるたび:

this.locations.forEach((o, i, a) => a[i] = a[i] + 's'); // update locations

*ngForは完全にあなたがクリックで追加されたクラスを削除し、最初からHTMLを再描画します。

<div *ngFor="let location of locations; let i = index;"> 
    <li id="location-{{i}}" (click)="selectLocation($event.target.id)">Hello {{location}}</li> 
</div> 

トリックを確認することですがこのクラスが設定されている場合は、再描画に残ります。このような何か(ここでは完全なソリューション:https://plnkr.co/edit/6PTWU6dpQLSa5c3tVDbg):

<div *ngFor="let location of locations; let i = index;"> 
    <li id="location-{{i}}" (click)="selectLocation($event.target.id, i)" [ngClass]="{selectedLocation: selectedLocationIndex == i}">Hello {{location}}</li> 
</div> 

ではなくHTML要素のIDを追跡するには、私の解決策は、ちょうど我々はすでにlet i = indexで追跡した*ngForループのインデックスを、追跡する($event.target.idを渡すことはなくなりました必要ですが、何かを傷つけることはありません)。

私たちのループのインデックスiが現在トラッキングしている選択されたアイテムのインデックスとselectedLocationIndexと一致する場合は、を使用して 'selectedLocation'クラスを設定/削除します。

+1

右バディ行きます。そして、一般的に言えば、必要がない限り直接DOMを操作しないでください。私。 'document.getElementById(locationID).classList.add( 'selectedLocation')'は本当に悪いです。 '[ngClass]'は行く方法です。 –

+0

多くのクリーナー。ありがとうございました。私は[ngClass]と[class.selectedLocation]を交互に使うことができたという印象を受けました。後者は「最初から式が変化しました」というエラーを出しました。 – dexter

1

ここでは、

//our root app component 
import {Component, NgModule, VERSION} from '@angular/core' 
import {BrowserModule} from '@angular/platform-browser' 

@Component({ 
selector: 'my-app', 
template: ` 
<h3> Select an item </h3> 
<div *ngFor="let location of locations; let i=index;"> 
<div [ngClass]="{'selectedLocation':selectedLocation==i}"> 
    <li (click)="selectLocation(i)">Hello {{location}}</li> 
</div> 
</div> 
` 
}) 
export class App { 
selectedLocation; 
locations: Array = ["World", "Mars", "Saturn", "Pluto"]; 

constructor() { 
// datasource updates every sec 
setInterval(() => { 
    this.locations.forEach((o, i, a) => a[i] = a[i] + 's'); // update locations 

    // if (this.selectedLocationID) document.getElementById(this.selectedLocationID).classList.add('selectedLocation'); 

    setTimeout(() => { 
    //if (this.selectedLocationID) document.getElementById(this.selectedLocationID).classList.add('selectedLocation'); 
    }, 0); 

}, 1000); 
} 

selectLocation(i) { 
this.selectedLocation = i; 
} 
} 

@NgModule({ 
imports: [ BrowserModule ], 
declarations: [ App ], 
bootstrap: [ App ] 
}) 
export class AppModule {} 
関連する問題