angularngforng-style

How to use ngFor index in ngStyle for specific item?


I have these lines of code

<div class="picture"
           *ngFor="let item of data?.slice(0, data.length / 3); index as i">
        <div class="shadow"
             (mouseenter)="showShadow()"
             (mouseleave)="hideShadow()"
             [ngStyle]="{'background-color': shadow}">
          <img src="{{item.urls.small}}" alt="">
        </div>
      </div>

It's working fine, but the problem is that I can't solve how to make shadow visible for specific div, not for all of them when mouse is entering. Just like how it realized on unsplash

TS file

shadow = 'rgba(0, 0, 0, 0)';

showShadow(): void {
    this.shadow = 'rgba(0, 0, 0, 0.3)';
  }

  hideShadow(): void {
    this.shadow = 'rgba(0, 0, 0, 0)';
  }

Also SCSS file if someone need it

.picture {
      margin: 8px;

      .shadow {
        position: relative;
        width: inherit;
        height: inherit;

        img {
          position: relative;
          z-index: -1;
        }
      }
    }

Solution

  • Directives are your friend here. This is a typical use-case for Attribute Directives. Instead of using [ngStyle] and (mouseenter), (mouseleave), use a directive.

    The said directive class would look like this. (Copied as is from Angular docs).

    Directive

    import { Directive, ElementRef, HostListener } from '@angular/core';
    
    @Directive({
      selector: '[appHighlight]'
    })
    export class HighlightDirective {
      constructor(private el: ElementRef) { }
    
      @HostListener('mouseenter') onMouseEnter() {
        this.highlight('yellow');
      }
    
      @HostListener('mouseleave') onMouseLeave() {
        this.highlight(null);
      }
    
      private highlight(color: string) {
        this.el.nativeElement.style.backgroundColor = color;
      }
    }
    

    And your element would be:

    <div appHighlight>
        <img ..... >
    </div>