2012-03-07 22 views
11

Come posso annullare una promessa senza rimuovere l'elemento dal DOM?Annullamento di una promessa differita in jQuery

fiddle

ho corse di questo codice:

$("#box") 
    .delay(2000) 
    .show("slow") 
    .delay(2000) 
    .promise()        
    .then(function(){log("Done");}); 

Dopo questo, c'è un modo per annullare la promessa? Sia clearQueue() e stop(true) non hanno funzionato, perché non è un'animazione che sto tentando di annullare. Ho visto che remove() dovrebbe farlo ... ma voglio solo fermare la promessa, non rimuovere l'intero elemento.

+1

Se si ha solo l'oggetto promessa (e nessun accesso all'originale differito), allora dovrebbe essere impossibile farlo. L'idea di una promessa è quella di essere in grado di ascoltare il differito di essere risolto o rifiutato, senza la funzionalità di risoluzione/rifiuto. Quello che puoi fare è creare un wrapper di promessa che esponga le funzioni originali di promessa, ma tutte le callback sono vincolate con una funzione wrapping che ascolta un qualche tipo di flag per evitare di attivare la callback se il differito viene contrassegnato come cancellato. –

+0

quasi, in realtà vuoi solo creare un rinvio e rifiutarlo o risolverlo manualmente come meglio credi. –

risposta

4

Buone notizie. Da ieri puoi cancellare la tua promessa.

Ho pubblicato la nuova versione del mio piccolo plug-in jquery-timing che fornisce due metodi tra molti altri chiamati .wait() e .unwait().

var deferred = $("#box").delay(2000).show("slow").delay(2000).promise(); 
$.wait(deferred, function(){ log("Done"); }); 

Se poi si desidera annullare la registrazione del callback:

$.unwait(); 

Queste versioni statiche di attesa e unwait anche il supporto nome di un gruppo opzionale per non annullare qualsiasi gestore, ma solo una serie specifica.

Oltre a questo si può fare molto cose più intelligente come:

$('#box').wait(deferred).addClass('ready'); 

o l'intero codice in una catena, senza opzione unwait:

$("#box").delay(2000).show("slow") 
    .delay(2000).join(function(){log("Done");})).addClass('ready'); 

o lo stesso ancora più brevi, con possibilità di annullare le due pause:

$("#box").wait(2000).show("slow",$) 
    .wait(2000, function(){log("Done");})).addClass('ready'); 

Basta vedere i documenti, gli esempi e l'API che si adatta meglio per voi.

+0

solo una domanda: non posso usare deferred.reject()? –

2

Credo che si può utilizzare $('#box').remove();

Dalla documentazione jQuery qui: http://api.jquery.com/promise/

La restituito promessa è legata ad un oggetto differita memorizzato sul .data() per un elemento. Poiché il metodo .remove() rimuove sia i dati dell'elemento che l'elemento stesso, impedirà la risoluzione di qualsiasi promessa irrisolta dell'elemento. Se è necessario rimuovere un elemento dal DOM prima della sua promessa viene risolto, utilizzare .detach(), invece, e seguire con .removeData() dopo la risoluzione."

+0

Bene, ho visto 'remove(), ma mi stavo chiedendo se c'è un modo per farlo senza rimuovere l'elemento reale. Domanda a cura – ripper234

+1

Sì, dovendo rimuovere l'elemento dal dom non sembra l'ideale. Era l'unico modo per farlo funzionare. Buona fortuna nella ricerca di una soluzione migliore. – Paul

1

Non credo che ci si vuole qualcosa di come http://jsfiddle.net/2cq8M/? Sto coinvolgendo due promesse (una solo per gestire il caso alla fine del set di animazioni, l'altra da risolvere o rifiutare secondo necessità)

+0

Ovviamente, la cosa più grande di cui sono curioso è che cosa dovrebbe accadere alle animazioni una volta che rifiuti la promessa? – JayC

+0

Sintassi un po 'goffa ... Speravo in un modo per annullare effettivamente una promessa ... potrebbe non esserci un modo nell'attuale implementazione. – ripper234

1

Si desidera utilizzare un differito in questo caso invece di una promessa, tuttavia, è possibile utilizzare la promessa dell'animazione per risolvere il differito

http://jsfiddle.net/LG9eZ/9/

var stopDone = true; 

function log(msg) { 
    $(".debug").append(new Date() + " - " + msg + "<br/>"); 
} 

log("Starting"); 

var boxAnimation = new $.Deferred(); 
boxAnimation.done(function() { 
    log("Done"); 
}); 
boxAnimation.fail(function() { 
    log("Stopped"); 
}); 


$("#box").delay(2000).show("slow").delay(2000).promise().then(function() { 
    boxAnimation.resolve(); // when all the animations are done, resolve the deferred. 
}); 


if (stopDone) 
{ 
    boxAnimation.reject(); 
} 

Come nota a margine, i differiti possono essere rifiutati o risolti una sola volta. Una volta che vengono rifiutati o risolti, non è possibile modificare il loro stato.

Problemi correlati