Si un élément HTML a été ajouté au DOM (par exemple après avoir cliqué sur un bouton), comment pouvons-nous accéder à cet élément ? viewChild ne peut pas le voir.
Mise à jour 1 : Plus de description
J'ai utilisé jquery datatable ( Version de jquery.dataTables definitelyTyped ). Sur la base de este je peux ajouter une nouvelle colonne et définir le html à l'intérieur de celle-ci. J'ai écrit ce 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
},
],
Avec les outils pour développeurs de Chrome, je vois ceci :
La première balise d'ancrage fonctionne mais avec href, pas routerLink.
La deuxième balise d'ancrage ne fonctionne pas parce que les directives angulaires ne sont pas conformes à href.
J'ai essayé d'utiliser DynamicComponentLoader pour le compiler, et j'ai modifié le code comme ceci :
Mais je ne peux pas accéder à l'élément #target avec viewChild (je veux le remplacer par un autre composant par loadNextToLocation). Je pense que ce n'est pas la meilleure façon d'obtenir un bon résultat.
Je veux utiliser un routerLink avec des boutons de commande dans une table de données jquery.
Pouvez-vous m'aider à résoudre ce problème ?
Merci d'avance.
solution :
Si vous voulez ajouter du HTML au DOM avec du javascript ou une fonction de rappel, déterminez d'abord une balise à partir du modèle qui peut être un parent pour ces éléments à l'avenir.
-
Ajoute une variable de modèle à cet élément parent (#target par exemple).
<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>
-
Ensuite, ajoutez une classe simple et un attribut simple à votre code html (ce code est généré après la compilation de la page avec Angular, vous pouvez également écrire du code avec typescript ou javascript pour générer du 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 }, ],
-
Maintenant, importez et injectez ces sources dans votre composant :
import {ViewChild, Renderer} from '@angular/core';
et :
constructor(private renderer: Renderer, private router: Router)
-
Définissez une variable viewChild dans votre classe de composant :
@ViewChild('target') target;
-
Écrivez une fonction comme celle-ci :
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) }
}
-
Vous devez trouver le meilleur endroit pour appeler cette fonction, par exemple, le callback des données ajax est un choix et appeler AfterEverything() à l'intérieur de celui-ci. Vous pouvez appeler cette fonction à l'intérieur de ngAfterViewInit().
Notez que parfois un délai de plusieurs secondes est nécessaire pour s'assurer que tous les nouveaux éléments sont créés.