0

I have created a table, and I am able to generated a new row to the table on calling of addRow() function. generated button in the row is not able to call the myFunc(). how can I achieve that.

addRow(){
  let table = document.getElementById("tableData");
  let rowcount = table.rows.length;
  let row = table.insertRow(rowcount);
  row.insertCell(0).innerHTML= rowcount;
  row.insertCell(1).innerHTML= 'some fake data';
  row.insertCell(2).innerHTML= '<button (click)="myFunc()">click</button>';
  }

  myFunc(){
    alert()
  }
<table id="tableData" border="1" >
  <tr>
    <th>S.No.</th>
    <th>Name</th>
    <th>Operation</th>
  </tr>
</table>

2
  • 3
    Is there a reason you're generating that html? You could do the same functionality via ngIf Else. The reason it's not executing is because when your TS is compiled to JavaScript it hasn't made the link to that function Commented Sep 6, 2017 at 7:53
  • 1
    you cannot add events to dynamically created html Commented Sep 6, 2017 at 7:54

3 Answers 3

2

It seems that you don't understand the core principles of angular, don't manipulate the DOM directly when you don't have to. You should store your rows in an array and then loop trough it inside your template.

If you want to add a row, just add a new element to the array and angular will do the rest.

Components template:

<table>
  <tr>
    <th>S.No.</th>
    <th>Name</th>
    <th>Operation</th>
  </tr>
  <tr *ngFor="let row of myRows; let i = index">
    <td>{{ i + 1 }}</td>
    <td>{{ row.data }}</td>
    <td>
      <button (click)="myFunc()">click</button>
    </td>
  </tr>
</table>

And in your component:

public myData: { data: string }[] = [];

public addRow() {
  this.myData = this.myData.concat({
    data: 'some fake data'
  });
}

I strongly recommend that you should read the Fundamentals section of the docs.

Sign up to request clarification or add additional context in comments.

2 Comments

What do you derive from that trackBy would be required?
In this case it's not required, was a habit to use it, i removed it to keep it simple.
0

The only way to make (click) or similar Angular specific stuff work for dynamically added HTML is to compile a component at runtime.

You can still do something like

constructor(private elRef:ElementRef) {}

addRow() {
  let table = document.getElementById("tableData");
  let rowcount = table.rows.length;
  let row = table.insertRow(rowcount);
  row.insertCell(0).innerHTML= rowcount;
  row.insertCell(1).innerHTML= 'some fake data';
  row.insertCell(2).innerHTML= '<button (click)="myFunc()">click</button>';

  this.elRef.nativeElement.querySelector('button').addEventHandler('click', this.clickHandler.bind(this));
}

4 Comments

But please don't do this. :( Learn how to use Angular's native directives. If this is how you're going to build your app, then you shouldn't use Angular at all: it's actually just slowing you down (both you and the app).
Even if (and i don't know a reason why) you want to do it like this, use the Renderer (Renderer2) to bind the click event! And addEventHandler doesn't exists.
I don't know what the current stance is from the Angular team. In the 2.0.0 pre-release phase they strongly suggested using Renderer, then there was a time where it was mentioned several times that it's not a strong suggestions, only if you consider using Server Side Rendering or WebWorker. Then I didn't hear or see anything about this topice, but also didn't have that much time to follow that closely.
I am geeting error when I am implementing this Cannot read property 'bind' of undefined
0

using render2 angular way to do it.

@ViewChild('myButton') myButton;
  let simple = this.renderer.listen(this.myButton.nativeElement, 'click', (evt) => {

                console.log('Clicking the button', evt);
                this.myFunc() //your func

            });

refer LINK for more infirmation.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.