2016-11-11 2 views
1

ich eine Hauptansicht, die einen Kasten hat, die Subviews hat, die Sie zwischenBackbone - verhindert verzögerte Ausführung nach Ansicht entfernt wird

Nach einem Abruf Ajax-Aufruf erfolgreich ist, ein ‚Erfolg‘ div auf der Hauptansicht wechseln wird gezeigt.

Das Problem, mit dem ich konfrontiert bin, ist, dass, wenn ich zwischen Subviews wechsle, die verzögerte Zusage aus dem Abruf der vorherigen Ansicht ausgeführt wird und das 'Erfolg' div.

dies ist mein Code:

this.model.fetch().done(function() { 
    $('#success').show(); 
}); 

onChangeSubview: function() { 
    this.subview.unbind(); 
    this.subview.remove(); 
} 

Diese Frage SO abort-ajax-requests-using-jquery sagt, dass Sie den Zeiger speichern, um die es verschoben und stoppen, indem wie so abbrechen() aufgerufen:

var fetchXhr = this.model.fetch().done(function() { 
    $('#success').show(); 
}); 
onChangeSubview: function() { 
    fetchXhr.abort(); 
} 

Ich habe mehr Fetches für jede Teilansicht und einige werden in einem Intervall wiederholt, das würde bedeuten, dass ich jede Abrufanforderung speichern und durch sie durchlaufen müsste, die jeweils abbrechen.

Gibt es eine bessere Möglichkeit, die Ausführung der zurückgestellten Funktion zu stoppen? zB: eine Art von Prüfung, um zu sehen, ob die Unteransicht entfernt wurde, oder eine Funktion, um alle verzögerten Versprechungen zu lösen?

+1

Nur laut gedacht, könnten Sie alle Ihre Abrufe für eine Unteransicht zu einer Liste hinzufügen und dann onChangeSubview können Sie über sie iterieren und den Abbruch z. 'this.fetches.forEach (function (fetchXhr) {fetchXhr.abort();});' (oder '_.invoke (this.fetches, 'abort');' wenn Du es auf Underscore-Art machen willst). Sie könnten diese Funktionalität möglicherweise sogar in eine Basisansicht einfügen, die Sie erweitern, sodass Sie etwas davon abstrahieren können. – Dymos

+1

@Dymos +1. Du bist zu bescheiden, das ist kein Kommentar, sondern eine wirkliche Antwort;) – hashchange

+0

haha ​​danke :-) Ich werde es dann als Antwort für die Nachwelt hinzufügen. – Dymos

Antwort

1

Das Abbrechen ist nicht unbedingt wünschenswert, da Sie möchten, dass die Ansichten auch dann weiterhin aktualisiert werden, wenn sie ausgeblendet sind (dies wird dadurch bestätigt, dass Sie gerade die Verbindung trennen/entfernen).

Sie können natürlich auch die Notwendigkeit, durch die Annahme eines Musters zum Abbruch vermeiden, die die ‚#success‘ Element verursacht mit einem Verfahren durch Rigging ein $('#success') Objekt gezeigt bedingt, zB werden, die eine Funktion gibt, die das #success Element zeigt nur, wenn ein Eine bestimmte Unteransicht (oder ihr Container) ist sichtbar (oder welches Kriterium auch immer passt).

// in some suitable outer context 
var $success = $('#success'); 
$success.showConditional = function($container) { 
    var $self = $(this); 
    return function() { 
     if($container.is(':visible')) { 
      $self.show(); 
     } 
    } 
}; 

... 

$subviewContainer = $("someSelector"); //or maybe the container is already a property of this or this.model? 
this.model.fetch().done($success.showConditional($subviewContainer)); 

Mit diesem Muster an Ort und Stelle für alle Abholungen, wird das #success Element zeigt nicht versteckt oder entfernt Subviews.

Das ist das Prinzip sowieso. Möglicherweise müssen Sie das Detail an Ihr Gesamtmuster anpassen.

+0

War das gleiche Ding aber war nicht sicher, wie man für ein entferntes Objekt prüft. Sie haben die Idee, das DOM für das Cache-JQuery-Element der Ansicht zu überprüfen, das beantwortet, aber ich war besorgt, dass es rechenintensiv wäre, stattdessen habe ich Folgendes getan: Die übergeordnete Ansicht ruft derzeit thisviews.cleanup() auf. ; wenn die Unteransicht entfernt wird. Ich habe ein Feld "removed" in der Aufräumfunktion der Unteransicht hinzugefügt und gesetzt: cleanup: function() { this.removed = true; this.remove(); this.unbind(); } Und in der Ajax-Aufruf, ich habe die Prüfung: this.model.fetch(). Immer (wenn (!! self.removed) {return;} -code-); – Ta946

+1

Sieht cool aus. Sie können '.cleanup()' syntaktisch sauberer machen, indem Sie 'true' von' .remove() 'zurückgeben, um' this.removed = this.remove() 'zu schreiben. Eigentlich wäre das nützlich, wenn 'this.remove()' manchmal fehlschlagen (dh nicht entfernen) würde, in diesem Fall (vielleicht mit Hilfe von try/catch) könnte es 'false' zurückgeben. –

1

Eine Möglichkeit, dies zu lösen, wäre, alle Ihre Abrufe für eine Unteransicht zu einer Liste hinzuzufügen und dann onChangeSubview über sie zu iterieren und den Abbruch z.

this.fetches.forEach(function(fetchXhr) { 
    fetchXhr.abort(); 
}); 

oder wenn Sie wollen es die Unders Art und Weise tun

_.invoke(this.fetches, 'abort'); 

Sie könnten möglicherweise sogar diese Funktionalität in einer Basisansicht setzen, die Sie so erweitern Sie konnten weg einige davon abstrakt.

+0

Ist das der "bessere Weg", den das OP sucht, oder die Art, wie er es bereits weiß? –

+0

es ist eine andere Art und Weise :) - welcher Wert es bringt, ist im Auge des Betrachters – Dymos

Verwandte Themen