如何在this.el.nativeElement.querySelector('selector')上调用addEventListner,其中el是elementRef

时间:2018-08-10 13:18:55

标签: angular

我正在使用angular 5,并且有一个简单的要求,即我需要在函数中创建一些html,然后将其循环以将click事件绑定到它们。

我之前做过:

userslist.component.ts

import { Component, Input, ElementRef} from '@angular/core';
enter code here
 constructor(private el: ElementRef){}

createUserList(){

    this.userList= _cityList.map(list => {
      return `<li class="list-users" >${list.display_name}<span class="hide" >${list.name}</span></li>`;
    }).join('');

this.el.nativeElement.querySelectorAll('li.list-users').forEach(ele => {

 ele.addEventListener('click', this.selectUsers.bind(this));
}

} 有了这个我在IE中出现错误:

  

错误TypeError:对象不支持属性或方法“ forEach”

所以我将其更新为:

  const listUsers= Array.from(document.querySelectorAll(".list-users"));

        listUsers.forEach((ele) => {
          ele.addEventListener('click', this.selectUsers.bind(this));
        })

这在IE和其他浏览器中有效。但是我不想使用文档来访问DOM元素。

如果我写:

   const listUsers= Array.from(this.el.nativeElement.querySelectorAll(".list-users"));

        listUsers.forEach((ele) => {
          ele.addEventListener('click', this.selectUsers.bind(this));
        })

然后我在tslint中出错:

  

类型'{}'上不存在属性'addEventListener'

this.el.nativeElement.querySelectorAll(“。list-users”)和document.querySelector的输出相同。

然后为什么Array.from不将前者转换为数组。

需要以角度方式解决此问题,而不是直接使用文档对象。

我从两个地方得到的输出:

NodeList(5)  0:li.list-users
1:li.list-users
2:li.list-users
3:li.list-users
4:li.list-users

谢谢!

2 个答案:

答案 0 :(得分:2)

对于初学者,请停止使用香草JS。

Angular是一个完整的框架,还通过其Renderer支持动态DOM操作。

第二,在这种情况下,您应该改为使用ViewChildren装饰器以及渲染器。

This stackblitz向您展示其工作方式。打开控制台,然后单击项目。

import { Component, Input, Renderer2, QueryList, ViewChildren, ElementRef } from '@angular/core';

@Component({
  selector: 'hello',
  template: `<ul>
        <li *ngFor="let i of [0, 1, 2, 3]" #listItems>Index is {{ i }}</li>
      </ul>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
  @Input() name: string;

  @ViewChildren('listItems') listItems: QueryList<ElementRef<HTMLUListElement>>

  constructor(private R: Renderer2) {
  }

  ngAfterViewInit() {
    this.listItems.toArray().forEach((item, index) => {
      this.R.listen(item.nativeElement, 'click', () => {
        console.log('You clicked on the item n° ', index);
      });
    });

  }
}

答案 1 :(得分:0)

您可以使用@ViewChildren和Renderer2侦听方法来处理click事件。这是stackblitz代码。 https://stackblitz.com/edit/angular-vzduhs