Angular 6: Делаем события одинаково динамичными на элементах * ngFor-dynamic-generated-template-elements

Обычно в Angular для отображения и скрытия вещей я создаю переменную в компоненте, создаю событие mouseover-mouseout для элемента, который переключает эту переменную, и помещаю ngIf на любой элемент, на который я хочу, чтобы это событие повлияло (отображение / скрытие).

Вы не можете подойти к этому так, если шаблон находится внутри ngFor. Когда вы наводите курсор на любой из динамически сгенерированных элементов, он запускает КАЖДОЕ отображение / скрытие. Таким образом, мой вопрос заключается в том, используя директивы Angular star, как я могу сделать события одинаково динамичными для * ngFor-dynamic-generated-template-elements, чтобы при наведении курсора на один из этих элементов шаблона генерировалось соответствующее событие? Более конкретно (см. Stackblitz ниже), как мне получить ОДНУ всплывающую подсказку, когда я наведен на соответствующее событие шаблона?

Как люди это обходят. Можете ли вы создать динамически генерируемые имена переменных? Будет ли это масштабируемым подходом, когда у вас есть сотни тысяч строк? Возможно нет. Должен быть способ.

Вот мой Stackblitz, демонстрирующий то, о чем я говорю.

Шаблон:

<h1>Tool tip example</h1>
<p>
  Events on dynamically generated template from *ngFor :)
</p>
<p>
  Requirements: Make a tooltip appear with the rest of the information on hover.
</p>


<table>
  <tr>
    <th>id</th>
    <th>name</th>
    <th>gender</th>
  </tr>
  <tr *ngFor="let object of this.data.arrayOfObjects">
    <td (mouseenter)="tooltipHover=!tooltipHover" (mouseleave)="tooltipHover=!tooltipHover" class="id-pointer">
      {{object.friends.length}}
        <div *ngIf="this.tooltipHover" class="tooltip">
Tooltip:
more info here

  </div>
    </td>
    <td>{{object.name}}</td>
    <td>{{object.gender}}</td>


  </tr>


</table>

Составная часть:

import { Component } from '@angular/core';
import {Data} from './../../data'

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  tooltipHover:boolean =false;

  constructor(public data: Data){}


}

person imnickvaughn    schedule 17.08.2018    source источник
comment
ваш stackblitz не работает   -  person Chellappan வ    schedule 17.08.2018
comment
stackblitz работает, но это не связано с вашим вопросом   -  person Chellappan வ    schedule 18.08.2018
comment
Извините, он обновлен   -  person imnickvaughn    schedule 20.08.2018


Ответы (2)


Попробуйте что-нибудь вроде этого

создать пустой массив

tooltipHover=[]

<tr *ngFor="let object of this.data.arrayOfObjects; let i = index">
    <td (mouseenter)="tooltipHover[i]=!tooltipHover[i]" (mouseleave)="tooltipHover[i]=!tooltipHover[i]" class="id-pointer">
      {{object.friends.length}}
        <div *ngIf="this.tooltipHover[i]" class="tooltip">
Tooltip:
more info here    
  </div>
    </td>
    <td>{{object.name}}</td>
    <td>{{object.gender}}</td> 
  </tr>

Пример: https://stackblitz.com/edit/angular-xbwxrw.

person Chellappan வ    schedule 17.08.2018

У вас есть одна переменная для всего списка, поэтому она запускается для каждой строки. Вместо этого у вас должен быть список видимости подсказок для каждой строки. Отметьте этот stackblitz

Я изменил ваш html на следующий

 <tr *ngFor="let object of this.data.arrayOfObjects; let i = index">
    <td (mouseenter)="onMouseEnter(i)" 
      (mouseleave)="onMouseLeave(i)" class="id-pointer">
      {{object.friends.length}}
        <div *ngIf="tooltipHover[i]" class="tooltip">
          Tooltip:
          more info here
       </div>
    </td>
    <td>{{object.name}}</td>
    <td>{{object.gender}}</td>

</tr>

И ваш component файл к этому

 tooltipHover: boolean[] = [];

  constructor(public data: Data){}

  onMouseEnter(index) {
    this.tooltipHover[index] = true;
  }

  onMouseLeave(index) {
    this.tooltipHover[index] = false;
  }
person Bunyamin Coskuner    schedule 17.08.2018