网站搜索

javascript - Angular2 - 从窗口点击检测实体点击?


我有许多通过 *ngFor 创建的项目 :

 <my-item *ngFor="let item of myArray" [p]="item" > </my-item>

我可以通过监听click事件

 <my-item ... (click)="doWork(item) > </my-item>

但我不想附加这么多事件处理程序(因为我在那个 ngFor 上有很多组件)。

我在想是否可以将事件处理程序附加到 window 对象(只附加一次)(通过 @HostListener),然后分析 event 的 target 属性,并获取实际被点击的 Entity——但我没有成功。

问题:

我已经做了这个 plunker,它已经监听了一个 window click。
但是我如何才能获取被点击的 item 的实际引用(在 *ngFor="let item of myArray" 中)?

换句话说:

export class App {
  myArray:Person[] = new Array<Person>();

  @HostListener("window:click", ['$event'])
   onWindowclick() {
   console.log('click') 
   // how can I get a reference to the currently clicked item (as a `Person` entity) ?

  }

注意,我更倾向于不附加ID,然后在数组中搜索该ID

答案#1

通过使用如下自定义指令来处理它

import { Directive, HostListener, Renderer, ElementRef } from '@angular/core';
@Directive({
    selector: '[cicked]'
})
export class ClickDirective{

    constructor(
        private renderer: Renderer,
        private el: ElementRef
    ){}

    @HostListener('click') onClick() {
      this.el.nativeElement.attributes[..] // using this you handle handle the entity clicked
     console.log('some thing key upped')

    }
}

在演示中更新的指令中,使用此行作为所需参数

console.log(JSON.stringify(this.el.nativeElement.attributes['ng-reflect-p'].nodeValue));

实时演示

答案#2

我在玩你的 Plunkr,我老实说,我认为这在 Angular2 中不可能(或不打算实现)。

我认为可能可行的一些临时解决方案:

在 my-item 内添加一个 display: none 的输入文本作为子元素,并将其 [value] 绑定设置为 p: Person

这显然不起作用,[value] 绑定只能是字符串

与上面相同,但使用带有 [ngValue] 绑定的 <\select> 标签的第一个选项 这种方法本可以保留完整的 Person 对象,但 Angular 不将 value 属性暴露给 DOM,因此无法从 Window 事件访问。

现在,我有些犹豫要说这是不可能的——因为我绝不是专家,但我建议无论如何都坚持使用事件处理程序。

在你的数组中的每个项目添加事件处理程序时,开销将会非常小。