2016-05-24 19 views
5

Se un elemento HTML è stato aggiunto al DOM (ad esempio dopo aver fatto clic sul pulsante), come possiamo accedere a questo elemento? viewChild non può vederlo.Come viewChild può ottenere elementi aggiunti con js in angular2?

Update 1: più Descrizione

Ho usato jQuery datatable (jquery.dataTables definitelyTyped version). Base sul link this, posso aggiungere una nuova colonna e definire html al suo interno. Ho scritto questo codice:

  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

Con gli strumenti di sviluppo di Chrome vedo questo: enter image description here

ancora prima di tag opere, ma con href, non routerLink.

Il secondo tag di ancoraggio non funziona perché le direttive angolari non sono conformi a href.

ho cercato di usare DynamicComponentLoader per compilarlo, e ha cambiato il codice come questo: enter image description here

ma non posso accedere #target elemento con viewChild (voglio cambiarlo con un altro componente da loadNextToLocation).. Penso che questo non sia il modo ottimale per ottenere un buon risultato.

Desidero utilizzare routerLink con pulsanti di comando all'interno di jquery datatable.

Potresti per favore aiutarmi nella giusta direzione per risolvere questo?

Grazie in anticipo.

soluzione:

Se si desidera aggiungere HTML DOM con javascript o qualche funzione di callback prima di determinare un tag dal modello che può essere un genitore per coloro elemento (s) in futuro.

  1. Add modello variabile a questo elemento genitore. (# Bersaglio per esempio)

       <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. Quindi aggiungere una semplice classe e un attributo semplice per il codice HTML (Questo codice viene generato dopo la pagina compilata con angolare, inoltre è possibile scrivere del codice con dattiloscritto o javascript per generare 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 
           }, 
          ], 
    
  3. Ora importare e iniettare queste fonti al componente:

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

    e:

    constructor(private renderer: Renderer, private router: Router) 
    
  4. Definire una variabile viewChild nella classe del componente:

    @ViewChild('target') target; 
    
  5. Scrivi una funzione come questa:

    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. È necessario trovare posto migliore per chiamare questa funzione, per esempio, AJAX callback dati è una scelta e chiamata AfterEverything() all'interno di quella. È possibile chiamare questa funzione all'interno di ngAfterViewInit().

noti che a volte è necessario un ritardo di alcuni secondi per garantire che tutti i nuovi elementi vengono creati.

+0

Come lo aggiungi? –

+0

Ad esempio, vedere questo: https://datatables.net/examples/advanced_init/column_render.html. Possiamo usare la funzione di rendering per aggiungere del testo (come HTML) all'interno di una colonna. Immagina di voler cambiare gli elementi creati con questa funzione. – MortezaDalil

+0

La soluzione che hai aggiunto alla tua risposta è fondamentalmente la stessa che ho spiegato con 'ElementRef'. Non parti dall'elemento host dei componenti ma un elemento più specifico come spiegato in http://stackoverflow.com/questions/32693061/angular-2-typescript-get-hold-of-an-element-in-the- template/35209681 # 35209681 –

risposta

0

Se si aggiunge HTML dinamico (come [innerHTML]="someHtml"), quindi è possibile utilizzare l'accesso DOM diretta (visto di buon occhio in Angular2) iniettando ElementRef e utilizzando ElementRef.nativeElement.querySelector...

Se il codice HTML viene generato utilizzando *ngFor è possibile aggiungere variabili di modello e interrogare per questi elementi come

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

e poi nella classe componente

@ViewChildren('someVar') elements; 

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

Grazie ma non ho potuto risolvere il mio problema. Ho aggiornato la mia domanda con maggiori dettagli. – MortezaDalil

+1

Le variabili del modello non funzionano quando l'HTML viene aggiunto dinamicamente. La tua domanda non mostra come l'HTML è stato aggiunto. Devi usare l'approccio 'ElementRef'. –

+0

Ho trovato una soluzione e l'ho aggiunta alla mia domanda. – MortezaDalil