2017-10-16 44 views
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,我的解決辦法只是跟蹤*ngFor循環的指數,我們已經與let i = index跟蹤(通過$event.target.id不再必需的,但不會傷害任何東西)。

然後,使用[ngClass]設置/刪除「selectedLocation」類,如果我們的循環,i的指標,我們現在與selectedLocationIndex跟蹤所選項目的索引相匹配。

+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 {} 
相關問題