2013-04-17 21 views
5

Sto cercando di creare la tabella che crea righe utilizzando ajax. il problema è che quando ho assegnato l'ascoltatore "click" sulla base del nome della classe è sempre chiamato tempo multiploIl listener "clic" viene eseguito più volte

il mio codice è

function fn_getAlertRules(parentRowId) { 
    $.ajax({ 
     type: "GET", 
     url: anyURL, 
     contentType: "application/json", 
     dataType: "json" 
    }).done(function(data) { 
     // create row to add to parent table's row 
     var s_rulesHtmlString = '<tr><td colspan="3" class="rules-parent-tr"><table><tbody>'; 
     $.each(data, function(i, name) { 
     s_rulesHtmlString += '<tr class="rule-tr">'; 
     s_rulesHtmlString += '<td class="eventid-td">Rule ID:'+ name.RuleId+'<span>' + name.OccuredEventId + '</span></td>'; 
     s_rulesHtmlString += '<td>' + name.Name + '</td><td>' + name.RuleDate + '</td>'; 
     s_rulesHtmlString += '</tr>'; 
     }); 
     s_rulesHtmlString += '</tbody></table></td></tr>'; 
     // add row below parent tr 
     $(parentRowId).parent().after(s_rulesHtmlString); 
     $(".rule-tr").on("click", "td", function(event) { 
      // this code blocks get executed multiple times 
     }); 
    }); 
} 

Qualcuno può dirmi, motivo per cui è sempre chiamato tempo multipla ?

+0

Quante volte stai chiamando quella funzione? – JJJ

+0

fn_getAlertRules vengono chiamati solo una volta! solo il codice all'interno di .on ("click") viene chiamato tante volte quante sono le righe presenti –

+1

Il modello '$ (". regola-tr "). on (" clic "," td ", funzione (evento)' ha sostituito il vecchio evento 'live', che è stato utilizzato per associare gli elementi anche dopo che il dom è stato modificato, quindi su ogni chiamata ajax si stanno aggiungendo gli ascoltatori all'evento 'click' più e più volte – Candide

risposta

2

si sono vincolanti click evento in ciascuno (ciclo) e l'evento viene associato tutte le volte che viene eseguito il ciclo, motivo per cui si verificano ripetuti eventi di clic. È possibile delegare l'evento click all'elemento principale degli elementi da aggiungere o document prima che una chiamata e l'evento di jax vengano associati automaticamente all'elemento aggiunto dinamicamente aggiunto nella funzione done. Si può leggere di più su delega evento utilizzando il here

eventi delegati hanno il vantaggio di poter elaborare gli eventi da elementi discendenti che vengono aggiunti al documento in un secondo momento. Con selezionando un elemento che è garantito presente al momento in cui è collegato il gestore eventi delegato , è possibile utilizzare gli eventi delegati su evitare la necessità di collegare e rimuovere frequentemente gestori di eventi. Reference.

function fn_getAlertRules(parentRowId) { 
    $(document).on("click", ".rule-tr td", function(event) { 
     // this code blocks get executed multiple times 
    }); 

    $.ajax({ 
     type: "GET", 
     url: anyURL, 
     contentType: "application/json", 
     dataType: "json" 
    }).done(function(data) { 
     // create row to add to parent table's row 
     var s_rulesHtmlString = '<tr><td colspan="3" class="rules-parent-tr"><table><tbody>'; 
     $.each(data, function(i, name) { 
     s_rulesHtmlString += '<tr class="rule-tr">'; 
     s_rulesHtmlString += '<td class="eventid-td">Rule ID:'+ name.RuleId+'<span>' + name.OccuredEventId + '</span></td>'; 
     s_rulesHtmlString += '<td>' + name.Name + '</td><td>' + name.RuleDate + '</td>'; 
     s_rulesHtmlString += '</tr>'; 
     }); 
     s_rulesHtmlString += '</tbody></table></td></tr>'; 
     // add row below parent tr 
     $(parentRowId).parent().after(s_rulesHtmlString);  
    }); 
} 
2

Questo perché si dispone di più righe di tabella con la stessa classe assegnata. Se si desidera eseguirlo solo per l'elemento su cui si fa clic, assegnare un ID univoco a tale elemento.

+1

non sono sicuro che questo sia un problema ... perché mi sembrava simile e avevo il debug per lo stesso, ma in '$ (". Regola-tr ").on ("clic", "td", funzione (evento) { // usando $ (questo) ottengo solo quel td che è cliccato }); –

+0

Può usare anche questo che indica la riga cliccata invece di tutte le righe che condividono lo stesso nome di classe. – rahularyansharma

+1

@rahularyansharma Costruisci l'elemento dom con cose come 'var td = $ ('');', quindi aggiungi l'evento click su quel particolare elemento con 'td.click (function (event) {});' – Candide

0

Collegare il sull'evento clicca per solo l'ultimo <tr>, dopo l'ajax

$(".rule-tr :last").on("click", "td", function(event) { 
      // this code blocks get executed multiple times 
     });   
1

Credo che una soluzione (che ottimizzano le prestazioni troppo) è quello di utilizzare delegation. Pertanto, è possibile aggiungere un singolo gestore di eventi alla riga (o tabella padre) e agire in base all'oggetto event.target.

UPDATE: inoltre essere attento che il selettore $(".rule-tr") aggiungere il gestore di eventi anche alle righe aventi parent_id differente così una migliore soluzione potrebbe essere $(parent_Id + " .rule-tr") supponendo il parent_id è una stringa nella forma "#parent_id"

0

Forse si può provare ad evitare la ripetizione legare l'evento click

$(".rule-tr").unbind(); 
$(".rule-tr").on("click", "td", function(event) { 
      // this code blocks get executed multiple times 
     }); 
Problemi correlati