2012-05-19 11 views
8

all'interno di una funzione successo $ GetJSON, in primo luogo ho scatenare l'evento click di un altro elemento:

$('#' + data[0].ID).trigger('click'); 

L'evento click attivato ha un proprio metodo di $ GetJSON per caricare un po 'di dati in div. La riga successiva dopo l'evento innescata: In un primo momento il $ .each non sembra

$.each(data[0].ListEntries, function (key, val) { 
     //this relies on the triggered click event 
     //having completely loaded all data! 
} 

di fare qualsiasi cosa, ma ho aggiunto un diritto di allarme dopo l'evento innescata. Dopo aver risposto all'avviso, il codice in $ .each mostra come dovrebbe.

Immagino che $ .each sia in esecuzione prima che l'evento click finisca di caricare i dati.

setTimeout pausa abbastanza a lungo per l'evento click per caricare i dati, ma preferisco non impostare un tempo arbitrario:

setTimeout(function() { 
    $.each(data[0].ListEntries, function (key, val) { 
     //this relies on the triggered click event 
     //having completely loaded all data! 
    } 
}, 1000); 

Ho anche provato $ .quando e $ .poi senza alcun risultato (anche se l'aggiunta di avviso prima di $ .each all'interno $ .then crea ritardo per $ .each al lavoro):

$.when($('#' + data[0].ID).trigger('click')).then(function() { 
    $.each(data[0].ListEntries, function (key, val) { 
     //this relies on the triggered click event 
     //having completely loaded all data! 
    }) 

risposta

6

riordinato per una maggiore chiarezza

.trigger() restituisce un Oggetto jQuery in modo tale da negare l'opzione di fare $.when() ... $.then().

D'altra parte, .triggerHandler(), restituirà un oggetto di tua scelta, rendendo così possibile eseguire il trucco differito.

Il codice è organizzato in tre funzioni, semplificate di seguito. Il percorso di chiamata è 1,2,3 e il percorso di ritorno più importante è 3,2,1.

(1) La funzione (successo JSON) più alto livello includerà le seguenti righe:

function() { 
    ... 
    $.when($('#' + data[0].ID).triggerHandler('click')).done(function() { 
     $.each(data[0].ListEntries, function (key, val) { 
      ... 
     }); 
    }); 
    ... 
}; 

(2) Il gestore click innescato da (1), sarà il seguente:

$("img.Button").on("click", function() { 
    return GetModels(this.id);//here `return` passes on the jqXHR object, up the return path. 
}); 

(3) e la funzione di livello più basso, contenente la JSON, in cui (1) dipende, sarà di questa forma generale:

function GetModels(id) { 
    ... 
    var jqXHR = getJSON(function(){...}); 
    ... 
    return jqXHR;//it is vital to retutn the jqXHR object arising from the json call. 
} 

Note:

  • Il percorso di ritorno trasporta, come argomento "promessa" al metodo .when() in (1), l'oggetto jqXHR derivante dalla chiamata .getJSON() in (3). L'incatenato .done() in (1) è quindi costretto ad aspettare che il jqXHR sia risolto (cioè completo) prima di attivare la funzione fornita come argomento.
  • Il gestore di clic non fornisce alcuna ipotesi su come viene richiamato. Restituisce semplicemente l'oggetto jqXHR. Pertanto, quando invocato con .triggerHandler(), il gestore di clic può aggiungere ulteriori comportamenti senza influire sulla normale azione di clic.
  • Sarebbe più semplice chiamare GetModels() direttamente da (1), tagliando l'uomo medio (2), che va bene se il comportamento GetModels() è desiderato in modo univoco. Se, tuttavia, (1) deve essere in risposta a eventuali modifiche future al gestore di clic innescato (2), è necessario adottare l'approccio sopra riportato.
+0

event.preventDefault() nell'evento click innescato sta dicendo "L'oggetto non supporta questa proprietà o metodo". Il codice che imposta l'evento click è: $ ("img.Button"). On ("click", function() {GetModels (this.id);}); Questo è ciò che popola i div con i dati necessari per il codice OP. Qualcosa qui deve cambiare? –

+0

OK, per un img '.preventDefault()' non è necessario in quanto img non ha azioni predefinite, quindi la riga può essere cancellata. Per completezza sopra, l'ho lasciato, ma ho aggiunto un po 'di sicurezza per evitare l'errore. –

+0

Dang, ancora no go. Il $ dipendente non è ancora in attesa del completamento del clic. Penso che dovrò trovare un altro metodo per popolare questi dati dipendenti. –

0

Perché non provare un

$('#' + data[0].ID).live('click', function(){ 
    $.each(data[0].ListEntries, function (key, val) { 
      // your stuff here 
    }); 
}); 

Quindi il $.each dovrebbe essere eseguito solo dopo che il clic è stato attivato.

+0

L'evento click di solito carica i dati durante il clic dell'elemento senza dover ripetere i dati aggiuntivi. Un altro evento, descritto sopra, ottiene i dati del server per se stesso, quindi deve caricare gli stessi dati dall'evento del primo clic prima di iterare i dati aggiuntivi. –

+0

Hm .. Probabilmente ho frainteso la tua domanda come "Esecuzione di $ ciascuno solo dopo che il clic del trigger è completo". Colpa mia. – karthik

+0

Grazie comunque per il suggerimento, non sapevo nulla di .live; Sarò in grado di usarlo altrove, di sicuro. –

6

È possibile utilizzare un evento personalizzato per questo. Si potrebbe mettere la vostra $.each in un listener per l'evento e poi il vostro gestore successo $.getJSON potrebbe innescare quell'evento:

$('#x').click(function() { 
    var _this = this; 
    $.getJSON(url, data, function(data) { 
     // do things to data... 
     _this.trigger('data-loaded'); 
    }); 
}); 
$('#x').on('data-loaded', function() { 
    $.each(...) 
}); 
$('#x').click(); 

Demo: http://jsfiddle.net/ambiguous/FeYTB/

+0

Non sono sicuro se sto facendo qualcosa di sbagliato, ma non riesco a far funzionare il tuo suggerimento. Ho trovato questo comunque che funziona ... fondamentalmente impostando async su false prima di $ .getJSON e poi riportandolo su true in seguito. http://stackoverflow.com/questions/2765411/is-it-possible-to-set-asyncfalse-to-getjson-call –

+1

Ricorda che 'async false' non è una soluzione cross-browser. –

+0

@ChrisM: asynch è malvagio e raramente adatto. Cosa stai facendo in modo diverso rispetto alla demo e cosa significa "non funziona"? –

Problemi correlati