0

I am trying to apply angular animation to individual list item. On mouseover it gets some color and on mouseleave the color changes.

the list is being generated using ngFor.

Problem is when I hoverover one li item, all of the li items get highlighted.

// list component ts

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css'],
  animations: [
    trigger('usrSt', [
      state('active', style({ 'background-color': '#cfd8dc' })),
      state('inactive', style({ 'bacckground-color': '#fff' }))
    ])
  ]
})
export class ListComponent implements OnInit, OnDestroy {

  public personsList;
  st = 'active';
  @Input() coursestat: string;

  constructor(private getDt: InputDataService) {

  }

  ngOnInit() {
    this.personsList = this.getDt.personArr;
    console.log(this.personsList);
  }

  ngOnDestroy() {
    console.log('destroy list');
  }

  onMouseover() {
    this.st = 'active';
  }
  onMouseleave() {
    this.st = 'inactive';
  }

}

// list component html

<li class="list-group-item" (mouseover)="onMouseover()" (mouseleave)="onMouseleave()" [@usrSt]="st" [routerLink]= "['/users', i+1, person.name]" *ngFor="let person of (personsList | filter:coursestat:'chosenCourse'); let i = index">
SONGSTER
  • 585
  • 3
  • 11
  • 28

1 Answers1

0

Because you are using ngFor to loop every li and use same st

Solution:

Write a separated component for li and use animation for it.

Example

list.component.html

<app-my-li *ngFor="let person of (personsList | filter:coursestat:'chosenCourse'); let i = index"></app-my-li>

app-my-li.component.ts

@Component({
  selector: 'app-my-li',
  templateUrl: './app-my-li.component.html',
  styleUrls: ['./app-my-li.component.css'],
  animations: [
    trigger('usrSt', [
      state('active', style({ 'background-color': '#cfd8dc' })),
      state('inactive', style({ 'bacckground-color': '#fff' }))
    ])
  ]
})
export class ListComponent implements OnInit, OnDestroy {

  // you might wanna input user person data here

  st = 'active';

  constructor() { }

  ngOnInit() {
  }

  ngOnDestroy() {
  }

  onMouseover() {
    this.st = 'active';
  }
  onMouseleave() {
    this.st = 'inactive';
  }
}

app-my-li.component.html

<li  (mouseover)="onMouseover()" (mouseleave)="onMouseleave()" [@usrSt]="st"></li>

WITHOUT NEW COMPONENT

   export class ListComponent implements OnInit, OnDestroy {

  public personsList;
  sts = new Array<string>();
  @Input() coursestat: string;

  constructor(private getDt: InputDataService) {

  }

  ngOnInit() {
    this.personsList = this.getDt.personArr;

    // this.sts = Array.from(this.personalList, _ => 'active');
    this.personalList.forEach(_ => this.sts.push('active'));

    console.log(this.personsList);
  }

  ngOnDestroy() {
    console.log('destroy list');
  }

  onMouseover(i: number) {
    this.sts[i] = 'active';
  }
  onMouseleave(i: number) {
    this.sts[i] = 'inactive';
  }

}

<li class="list-group-item" (mouseover)="onMouseover(i)" (mouseleave)="onMouseleave(i)" [@usrSt]="sts[i]" [routerLink]= "['/users', i+1, person.name]" *ngFor="let person of (personsList | filter:coursestat:'chosenCourse'); let i = index">
Long Zhao
  • 143
  • 1
  • 1
  • 9
  • i didnt understand what you are saying. can you explain it in some more detail please – SONGSTER Oct 17 '17 at 12:39
  • you are creating a bunch of
  • that share a same variable 'st', thats the reason you have them all animate at same time. create individual component to hold individual state for each li will make it works
  • – Long Zhao Oct 17 '17 at 12:44
  • but thats couldnt be correct solution. how can we avoid using ngfor if we want to use animation – SONGSTER Oct 17 '17 at 12:46
  • Since you would like to animate a list of element, you need an array to hold their states. – Long Zhao Oct 17 '17 at 12:50
  • in your example the index `i` is not set dynamically. how do you set that – SONGSTER Oct 17 '17 at 13:16
  • i comes from ngFor loop index, each sts[i] is individual state holder for list – Long Zhao Oct 17 '17 at 13:27
  • i is not bound to any property in the component – SONGSTER Oct 17 '17 at 13:28
  • isnt there any easier solution like just getting the index and based on index set the value of the `st` – SONGSTER Oct 17 '17 at 13:29