0

Say I have a button:

<button (click)="clicked()" class="but">Click2</button>

And component:

export class AppComponent {

    but = document.querySelector('.but');

    clicked(){
      console.log(this.but);
    } 

    constructor(){
    }  

Console output is null here, because the button in DOM is not created yet, right? But why I can use its clicked() function if it is not created yet..?

Julius Dzidzevičius
  • 10,775
  • 11
  • 36
  • 81
  • Obviously because you bind `click` event on button element – yurzui Aug 03 '17 at 05:43
  • you cannot access the`DOM` like this in angular , if you need to access the `DOM` elements you need to use `Elementref` and `viewChild` and then you can add properties or attributes using `Rederer2` – Rahul Singh Aug 03 '17 at 05:43
  • clicked() function will be triggered, but it will display undefined or an empty array. – Raed Khalaf Aug 03 '17 at 06:04
  • 1
    `document.querySelector('.but')` is executed when `AppComponent` is instantiated, but at this time the DOM isn't rendered yet. As Rahul mentioned, you should avoid accessing the DOM using `document.querySelector` in Angular. – Günter Zöchbauer Aug 03 '17 at 06:18

1 Answers1

0

I believe that this question is a continuation of your another question Why I can't access template DOM element in the constructor of the component. There you had the following:

export class AppComponent {
    constructor(){
        button : HTMLElement = document.querySelector('button');
        refreshClickStream$ = Observable.fromEvent(this.button, 'click').subscribe();
    }

Console output is null here, because the button in DOM is not created yet, right?

And you are right about that as I explained in the mentioned answer.

But why I can use its clicked() function if it is not created yet..?

It's because Angular when constructing view nodes for the AppComponent will bind to the click event of the button. Since Angular creates these DOM elements it knows when it has to subscribe.

This all happens inside createViewNodes function:

function createViewNodes(view) {
    for (var i = 0; i < def.nodes.length; i++) {
        var nodeDef = def.nodes[i];
        switch (nodeDef.flags) {
            case 1 /* TypeElement */:
                var el = (createElement(view, renderHost, nodeDef));
                ...
                listenToElementOutputs(view, componentView, nodeDef, el); <--------------
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488