1

I have list of users. I want that when the cursor hover on the button, it sets *ngIf to true and then displays information about the user (and false when the cursor leave the button).

user-list.html:

<div *ngFor="let user of users">
  <h1>{{user.name}}</h1>
  <div onUserHover *ngIf="ngIf">
    <p>{{user.description}}</p>
  </div>
</div>

user-list.component.ts:

import { Component, OnInit } from '@angular/core';
import { User } from 'class/user';
import { UserService } from 'user/user.service';

@Component({
  selector: 'user-list',
  templateUrl: 'user-list.component.html',
  providers: [UserService]
})
export class UserListComponent implements OnInit {
  users: User[];
  
  constructor(private userService: UserService) {
  };

  ngOnInit(): void {
    this.getUsers();
  }

  getUsers(): void {
    this.userService.getUsers().then(users => this.users = users);
  }
    
  toggleUser(user: User): void {
    user.active = !user.active;
  }
}

I used "toggleUser(user: User)" like this : (click)='toggleUser(user)', however I want now a onHover instead of click.

I saw the tutorial about directives attributes on Angular.io website and a StackOverflow topic on HostBinding('ngIf').

Hostbinding ngIf in Angular2

onUserHover.directive.ts:

 import { Directive, ElementRef, HostBinding, HostListener } from '@angular/core';

@Directive({ selector: '[onUserHover]' })
export class OnUserHoverDirective {

    constructor(private el: ElementRef) {
    }

    @HostBinding('ngIf') ngIf: boolean;

    @HostListener('mouseenter') onMouseEnter() {
        console.log('onMouseEnter');
        this.ngIf = true;
    }

    @HostListener('mouseleave') onmouseleave() {
        this.ngIf = false;
    }
}

But I have one error on the browser :

Can't bind to `ngIf` since it isn't a known property of `div`

What can I do to implement this feature in Angular 2 style ?

Roman C
  • 49,761
  • 33
  • 66
  • 176
SolidCanary
  • 1,133
  • 1
  • 8
  • 15
  • You can simply do it with css , then why are you making things so complex ? – Vivek Doshi Mar 31 '17 at 11:48
  • @VivekDoshi I would prefer to do this in code as well, preventing CSS rules. Easier debugging. – Randy Mar 31 '17 at 11:49
  • You probably have an issue with the `this` binding, referring to the HTML element instead of your class. Try to bind the function to your class instead. – Randy Mar 31 '17 at 11:51
  • that does not make sense at all. You cannot access the parent ngIf from your directive, plus, you would like to append the content when it is hovered and removed when mouse leaves. How do you want to hover a non-existing element ? – n00dl3 Mar 31 '17 at 11:52
  • @n00dl3 If you look closely, you see that the `ngIf` is actually a very poorly named boolean and not the Angular `ngIf` module. – Randy Mar 31 '17 at 11:53
  • he cannot access the ngIf of the parent: `*ngIf="ngIf"` – n00dl3 Mar 31 '17 at 11:54
  • @n00dl3 Is that because it is a reserved keyword? He does declare it in his file as `@HostBinding('ngIf') ngIf: boolean;` – Randy Mar 31 '17 at 11:55
  • you cannot modify parent component variables except if it is explicitly specified with a banana in a box binding like `[(ngModel)]` and using an `EventEmitter` in the child... However, hovering a non-existing element is a mystery to me... – n00dl3 Mar 31 '17 at 11:57

1 Answers1

0

What you forgot is to bind the variable to the element

<div onUserHover [ngIf]="ngif" *ngIf="ngIf">

Your directive isn't working?

Did you remember to add the directive to the declarations attribute of @NgModule? It is easy to forget! Open the console in the browser tools and look for an error like this:

EXCEPTION: Template parse errors: Can't bind to 'myHighlight' since it isn't a known property of 'p'.

Angular detects that you're trying to bind to something but it can't find this directive in the module's declarations array. After specifying HighlightDirective in the declarations array, Angular knows it can apply the directive to components declared in this module.

Roman C
  • 49,761
  • 33
  • 66
  • 176