2016-05-24 6 views
5

Wenn dem DOM ein HTML-Element hinzugefügt wurde (zum Beispiel nach einem Klick auf den Button), Wie können wir auf dieses Element zugreifen? viewChild kann das nicht sehen.Wie ViewChild Elemente erhalten kann, die mit js in angular2 hinzugefügt wurden?

Update 1: Weitere Beschreibung

I jquery Datentabelle verwendet haben (jquery.dataTables definitelyTyped version). Basis auf this Link, ich kann neue Spalte hinzufügen und definieren HTML darin. Ich schrieb diesen 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

Mit Chrome-Entwicklertools ich sehen: enter image description here

Erste Anker-Tag funktioniert, aber mit href, nicht Router.

Das zweite Anker-Tag funktioniert nicht, weil die eckigen Anweisungen nicht mit href übereinstimmen.

Ich versuchte DynamicComponentLoader zu verwenden, um es zu kompilieren, und geändert Code wie folgt: enter image description here

Aber ich #target Element mit viewChild nicht zugreifen kann (will ich es von loadNextToLocation mit einer anderen Komponente ändern).. Ich denke, das ist kein optimaler Weg, um ein gutes Ergebnis zu erzielen.

Ich möchte RouterLink mit Befehlsschaltflächen in Jquery Datentabelle verwenden.

Könnten Sie mir bitte in die richtige Richtung helfen, um das zu lösen?

Vielen Dank im Voraus.

Lösung:

Wenn Sie HTML-DOM mit Javascript oder eine Callback-Funktion einen Tag aus Vorlage hinzufügen möchten bestimmen, die ein Elternteil für diejenigen Element sein kann (s) in der Zukunft.

  1. Add Template-Variable auf dieses übergeordneten Element. (# Ziel zum Beispiel)

       <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> 
    
  2. Dann eine einfache Klasse und ein einfaches Attribut zu Ihrem HTML-Code hinzufügen (Dieser Code wird generiert, nachdem die Seite mit eckig kompiliert wurde. Sie können auch Code mit typescript oder Javascript schreiben, um html zu erzeugen.

    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 
           }, 
          ], 
    
  3. Jetzt importieren und diese Quellen zu Ihrer Komponente injizieren:

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

    und:

    constructor(private renderer: Renderer, private router: Router) 
    
  4. definieren viewChild Variable in der Komponentenklasse:

    @ViewChild('target') target; 
    
  5. eine Funktion wie folgt schreiben:

    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) 
         } 
    

    }

  6. Sie müssen am besten Ort finden diese Funktion aufzurufen, beispielsweise Ajax-Daten Rückruf ist eine Wahl und rufen AfterEverything() im Inneren, dass. Sie können diese Funktion innerhalb von ngAfterViewInit() aufrufen.

Beachten Sie, dass manchmal eine Verzögerung von mehreren Sekunden erforderlich ist, um sicherzustellen, dass alle neuen Elemente erstellt werden.

+0

Wie fügen Sie es hinzu? –

+0

Zum Beispiel finden Sie hier: https://datatables.net/examples/advanced_init/column_render.html. Wir können die Renderfunktion verwenden, um Text (wie HTML) innerhalb einer Spalte hinzuzufügen. Stellen Sie sich vor, wir möchten Elemente ändern, die mit dieser Funktion erstellt wurden. – MortezaDalil

+0

Die Lösung, die Sie zu Ihrer Antwort hinzugefügt haben, ist im Grunde die gleiche wie die, die ich mit 'ElementRef' erklärt habe. Sie beginnen nicht mit dem Komponenten-Host-Element, sondern mit einem spezifischeren Element wie in http://stackoverflow.com/questions/32693061/angular-2-typescript-get-hold-of-an- element-in-the- Vorlage/35209681 # 35209681 –

Antwort

0

Wenn Sie HTML dynamisch (wie [innerHTML]="someHtml") hinzufügen möchten, dann können Sie direkt DOM-Zugang (verpönt in Angular2) verwenden, indem ElementRef Injektion und mit ElementRef.nativeElement.querySelector...

Wenn die HTML erzeugt wird *ngFor verwenden Sie Template-Variablen hinzufügen und Abfrage für diese Elemente wie

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

und dann in der Komponentenklasse

@ViewChildren('someVar') elements; 

ngAfterViewInit() { 
    console.log(this.elements); 
} 
+0

Vielen Dank, aber ich konnte mein Problem nicht lösen.Ich aktualisierte meine Frage mit mehr Details. – MortezaDalil

+1

Vorlagenvariablen funktionieren nicht, wenn der HTML-Code dynamisch hinzugefügt wird. Ihre Frage zeigt nicht, wie der HTML-Code hinzugefügt wurde. Sie müssen den 'ElementRef'-Ansatz verwenden. –

+0

Ich habe eine Lösung gefunden und sie zu meiner Frage hinzugefügt. – MortezaDalil