为什么我无法在组件的构造函数中访问模板DOM元素 [英] Why I can't access template DOM element in the constructor of the component

查看:105
本文介绍了为什么我无法在组件的构造函数中访问模板DOM元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从RxJS开始,想创建简单的按钮单击流,所以我只需这样做:

Starting with RxJS and want to create a simple stream of button clicks, so I simply do this:

export class AppComponent {

    button : HTMLElement = document.querySelector('button');

    refreshClickStream$ = Observable.fromEvent(this.button, 'click')
       .subscribe();

    constructor(){
    }  

但是在控制台中收到该错误...

but receive that error in console...

也这样尝试过:

  clicked(e) {
    return Observable.fromEvent(e.target, 'click')
    .do(console.log)
       .subscribe();
  }

但是第一次单击后,控制台中没有任何输出.第二次单击后,我得到一个MouseEvent对象.第三次单击后,我得到两个MouseEvent对象.第四次单击后,我得到其中的三个,依此类推.因此,我认为单击事件处理程序与RxJS fromEvent函数重复.

But after first click I get no output in console. After second click I get one MouseEvent object. After third click I get two MouseEvent Objects. After fourth click I get three of them etc. So I think click event handler duplicates with RxJS fromEvent function.

欢迎任何解释.

推荐答案

您具有以下设置:

AppComponent 
   template: '<button>some button</button>'
   button : HTMLElement = document.querySelector('button');

您在类中放入的顶级代码在转译为JavaScript时将用作构造函数的主体:

The top level code you put in the class will be used as a body of the constructor when transpiled to JavaScript:

class AppComponent {
   constructor() {
       let HTMLElement = document.querySelector('button');
   }
}

现在,Angular遍历组件树,并为每个组件一个接一个地创建带有DOM节点的视图.因此,它首先为承载app-component的组件创建一个视图.它为其生成DOM主机元素,然后调用AppComponent构造函数.此时,尚未创建带有按钮DOM元素AppComponent视图..因此,在执行构造函数时,您尝试查找尚未创建的DOM元素按钮.

Now, Angular goes through the tree of components and creates a view with DOM nodes for each component one by one. So it first creates a view for the component that hosts app-component. It generates a DOM host element for it and then calls the AppComponent constructor. At this point the view for the AppComponent with button DOM element hasn't been created yet. So when the constructor is executed, you try to find the DOM element button which is not yet created.

要执行您要执行的操作,可以使用任何生命周期挂钩.要获取更多信息,请阅读我对构造方法与ngOnInit之间的区别的答案.

To do you what you're trying to do you can use any of the lifecycle hooks. To get more information read my answer for the Difference between Constructor and ngOnInit.

除此问题外,我还建议使用@ViewChild进行DOM查询,并使用ngOnInit生命周期挂钩,如下所示:

Besides this problem, I would also advise to use @ViewChild for the DOM query and ngOnInit lifecycle hook like this:

template: `<button #b>...</button>`
...
class AppComponent {
   @ViewChild('b') button;

   ngOnInit() {
       this.refreshClickStream$ = Observable.fromEvent(this.button, 'click').subscribe();
   }
}

这篇关于为什么我无法在组件的构造函数中访问模板DOM元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆