How can viewChild get elements added using js in angular2?

If an HTML element has been added to the DOM (for example, after clicking a button), how can we access this element? viewChild does not see this.

Update 1: Read More

I used jquery datatable ( jquery.data tables are definitely type version ). Based on this link, I can add a new column and define the html inside this. I wrote this code:

columnDefs: [ { render: function (data, type, row) { return ` <a href="admin/edituser/` + row.UserId+ `" class="btn btn-outline btn-circle btn-sm green"><i class="fa fa-edit" > </i> Edit </a>`+ `<a [routerLink]="['Delete']" class="btn btn-outline btn-circle btn-sm red"><i class="fa fa-trash-o" > </i> Delete </a> `; }, targets: 5 }, ], 

enter image description here

With Chrome Developer Tools, I see the following: enter image description here

The first anchor tag works, but with href, not routerLink.

The second anchor tag does not work because angular directives do not match href.

I tried using DynamicComponentLoader to compile it and modified the code as follows: enter image description here

But I cannot access the #target element using viewChild (I want to change it using another component using loadNextToLocation). I think that this does not optimize the way to get a good result.

I want to use routerLink with command buttons inside a jquery datatable.

Could you help me in the right direction to solve this problem?

Thanks in advance.

decision:

If you want to add HTML to the DOM using javascript or some callback function, first define a tag from the template, which may be the parent for these elements in the future.

  • Add a template variable to this parent element. (e.g. # target)

      <th> Email</th> <th> Date </th> <th> Phone </th> <th> Commands</th> </tr> </thead> <tbody #target></tbody> <tfoot> <tr> <th> </th> <th> </th> <th> </th> <th> </th> </tr> </tfoot> </table> 
  • Then add a simple class and a simple attribute to your HTML code (this code is generated after the code compiled using angular). You can also write code with typescript or javascript to generate html).

      columnDefs: [ { render: function (data, type, row) { return ` `<a date-id="` + row.UserId + `" class="editbtn btn btn-outline btn-circle btn-sm red"> Edit</a> `; }, targets: 5 }, ], 
  • Now import and paste these sources into your component:

      import {ViewChild, Renderer} from '@angular/core'; 

    and:

      constructor(private renderer: Renderer, private router: Router) 
  • Define the viewChild variable in the component class:

      @ViewChild('target') target; 
  • Write a function like this:

     public AfterEverything() { var el: HTMLElement = this.target.nativeElement;//Make an Element Object console.log(el); var commands: NodeListOf<Element> = el.getElementsByClassName('editbtn');//Find Element Object to get all elements with a specefic class console.log(commands); for (var i = 0; i < commands.length; i++) { //Loop for add event or style console.log(commands[i]); //Sample event(Click for routing) this.renderer.listen(commands[i], 'click', (event: Event) => { var thisid = event.srcElement.getAttribute("date-id");//Get value from element console.log(thisid); this.router.parent.navigate(['EditUser', { id: thisid }]);//Use value to make routeLink console.log(event.srcElement.innerHTML); }); this.renderer.setElementStyle(commands[i], 'backgroundColor', 'yellow');//for change color(just sample) } 

    }

  • You should find a better place to call this function, for example, ajax data callback is one option and AfterEverything () call inside that. You can call this function inside ngAfterViewInit ().

Please note that sometimes a delay of several seconds is required to ensure that all new elements are created.

+4
source share
1 answer

If you add HTML dynamically (for example, [innerHTML]="someHtml" ), you can use direct DOM access (frowning in Angular2) by typing ElementRef and using ElementRef.nativeElement.querySelector...

If the HTML is generated using *ngFor , you can add the template and query variables for elements such as

 <div *ngFor="let x of y" #someVar></div> 

and then in the component class

 @ViewChildren('someVar') elements; ngAfterViewInit() { console.log(this.elements); } 
0
source

All Articles