如何在数组更新时保留* ngFor中的类?

时间:2017-10-16 22:07:28

标签: angular

我有一个简单的列表,需要在点击时选择其中一个项目。但是,每隔x秒,列表“刷新”,选择似乎就会丢失。

要将选择添加回新创建的元素,我引入了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中的“闪烁”?

2 个答案:

答案 0 :(得分: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]来设置/删除“已选择的位置”。 class,如果我们的循环索引i与我们正在跟踪selectedLocationIndex的所选项目的索引匹配。

答案 1 :(得分: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 {}