Ich möchte Benutzer vor nicht gespeicherten Änderungen warnen, bevor sie eine bestimmte Seite meiner Angular 2-App verlassen. Normalerweise würde ich verwenden window.onbeforeunload
, aber das funktioniert nicht für Anwendungen mit nur einer Seite.
Ich habe festgestellt, dass Sie sich in Winkel 1 an das $locationChangeStart
Ereignis anschließen können, um eine confirm
Box für den Benutzer zu erstellen, aber ich habe nichts gesehen, was zeigt, wie dies für Winkel 2 funktioniert, oder ob dieses Ereignis überhaupt noch vorhanden ist . Ich habe auch Plugins für ag1 gesehen, die Funktionen für ag2 bereitstellen onbeforeunload
, aber ich habe auch keine Möglichkeit gesehen, sie für ag2 zu verwenden.
Ich hoffe, jemand anderes hat eine Lösung für dieses Problem gefunden. Beide Methoden funktionieren für meine Zwecke einwandfrei.
quelle
Antworten:
Der Router bietet einen Lebenszyklus-Rückruf CanDeactivate
Weitere Informationen finden Sie im Tutorial für Wachen
Original (RC.x Router)
quelle
canDeactivate
wird, funktioniert dies nicht.Ich habe es als hilfreich empfunden, den
@HostListener
Dekorator zurcanDeactivate
Implementierung Ihrer Klasse hinzuzufügen , um auf dasbeforeunload
window
Ereignis zu warten, um auch Schutz vor Browseraktualisierungen, Schließen des Fensters usw. abzudecken (siehe @ ChristopheVidals Kommentar zu Günters Antwort für Details zu diesem Problem) . Bei korrekter Konfiguration schützt dies gleichzeitig vor In-App- und externer Navigation.Beispielsweise:
Komponente:
Bewachen:
Routen:
Modul:
HINWEIS : Wie @JasperRisseeuw hervorhob, behandeln IE und Edge das
beforeunload
Ereignis anders als andere Browser und fügen das Wortfalse
in den Bestätigungsdialog ein, wenn dasbeforeunload
Ereignis aktiviert wird (z. B. Aktualisieren des Browsers, Schließen des Fensters usw.). Das Navigieren innerhalb der Angular-App bleibt davon unberührt und zeigt die angegebene Bestätigungswarnmeldung ordnungsgemäß an. Diejenigen, die IE / Edge unterstützen müssen und bei Aktivierungfalse
desbeforeunload
Ereignisses keine detailliertere Meldung im Bestätigungsdialog anzeigen / möchten, möchten möglicherweise auch die Antwort von @ JasperRisseeuw für eine Problemumgehung sehen.quelle
@Injectable()
der PendingChangesGuard-Klasse hinzufügen . Außerdem musste ich PendingChangesGuard zu meinen Providern hinzufügen@NgModule
import { HostListener } from '@angular/core';
beforeunload
. Wenn Sie ein Observable zurückgeben, funktioniert es nicht. Möglicherweise möchten Sie Ihre Benutzeroberfläche für Folgendes änderncanDeactivate: (internalNavigation: true | undefined)
und Ihre Komponente folgendermaßen aufrufen :return component.canDeactivate(true)
. Auf diese Weise können Sie überprüfen, ob Sie nicht intern weg navigieren, umfalse
anstelle eines Observable zurückzukehren.Das Beispiel mit dem @ Hostlistener von stewdebaker funktioniert sehr gut, aber ich habe noch eine Änderung daran vorgenommen, da IE und Edge das "false" anzeigen, das von der canDeactivate () -Methode in der MyComponent-Klasse an den Endbenutzer zurückgegeben wird.
Komponente:
quelle
false
im Bestätigungsdialogfeld angezeigt wird. Ich habe Ihre Antwort geringfügig bearbeitet, um sie'$event'
in die@HostListener
Anmerkung aufzunehmen, da dies erforderlich ist, um in derunloadNotification
Funktion darauf zugreifen zu können .Ich habe die Lösung von @stewdebaker implementiert, die wirklich gut funktioniert, aber ich wollte ein nettes Bootstrap-Popup anstelle der klobigen Standard-JavaScript-Bestätigung. Angenommen, Sie verwenden bereits ngx-bootstrap, können Sie die Lösung von @ stwedebaker verwenden, aber tauschen Sie den 'Guard' gegen den hier gezeigten. Sie müssen
ngx-bootstrap/modal
auch ein neues hinzufügen und hinzufügenConfirmationComponent
:Bewachen
(Ersetzen Sie 'Bestätigen' durch eine Funktion, die ein Bootstrap-Modal öffnet und ein neues, benutzerdefiniertes anzeigt.
ConfirmationComponent
)bestätigung.Komponente.html
Bestätigung.Komponente.ts
Und da das Neue
ConfirmationComponent
ohne Verwendung einesselector
in einer HTML-Vorlage angezeigt wird , muss esentryComponents
in Ihrem Rootapp.module.ts
(oder wie auch immer Sie Ihr Root-Modul nennen) deklariert sein . Nehmen Sie folgende Änderungen vorapp.module.ts
:app.module.ts
quelle
Die Lösung war einfacher als erwartet. Verwenden Sie sie nicht,
href
da dies nicht von der Angular Routing-routerLink
Direktive use verwendet wird.quelle
Antwort vom Juni 2020:
Beachten Sie, dass alle bis zu diesem Zeitpunkt vorgeschlagenen Lösungen keinen wesentlichen bekannten Fehler bei Angulars
canDeactivate
Wachen behandeln:Dies wurde hier , hier und ausführlich hier diskutiert
Bitte lesen Sie meine Lösung für das hier gezeigte Problem , die dieses Problem sicher umgeht *. Dies wurde auf Chrome, Firefox und Edge getestet.
* WICHTIGE CAVEAT : In diesem Stadium wird der Vorwärtsverlauf gelöscht , wenn auf die Schaltfläche "Zurück" geklickt wird. Der Rückwärtsverlauf wird jedoch beibehalten. Diese Lösung ist nicht geeignet, wenn die Aufbewahrung Ihrer Vorwärtshistorie von entscheidender Bedeutung ist. In meinem Fall verwende ich normalerweise eine Master-Detail- Routing-Strategie, wenn es um Formulare geht. Daher ist es nicht wichtig, den Vorwärtsverlauf beizubehalten.
quelle