Saya ingin memperingatkan pengguna tentang perubahan yang belum disimpan sebelum mereka meninggalkan halaman tertentu di aplikasi sudut 2 saya. Biasanya saya akan menggunakan window.onbeforeunload
, tetapi itu tidak berfungsi untuk aplikasi satu halaman.
Saya telah menemukan bahwa di sudut 1, Anda dapat menghubungkan ke $locationChangeStart
acara untuk mengeluarkan confirm
kotak untuk pengguna, tetapi saya belum melihat apa pun yang menunjukkan cara membuat ini berfungsi untuk sudut 2, atau jika acara itu bahkan masih ada . Saya juga telah melihat plugin untuk ag1 yang menyediakan fungsionalitas untuk onbeforeunload
, tetapi sekali lagi, saya belum melihat cara untuk menggunakannya untuk ag2.
Saya berharap orang lain telah menemukan solusi untuk masalah ini; metode mana pun akan bekerja dengan baik untuk tujuan saya.
sumber
Jawaban:
Router menyediakan callback siklus hidup CanDeactivate
untuk lebih jelasnya lihat tutorial penjaga
asli (RC.x router)
sumber
canDeactivate
ini tidak akan berfungsi.Untuk juga melindungi penjaga dari penyegaran browser, menutup jendela, dll. (Lihat komentar @ ChristopheVidal untuk jawaban Günter untuk detail tentang masalah ini), saya merasa terbantu untuk menambahkan
@HostListener
dekorator kecanDeactivate
implementasi kelas Anda untuk mendengarkanbeforeunload
window
acara tersebut. Jika dikonfigurasi dengan benar, ini akan melindungi dari navigasi dalam aplikasi dan eksternal pada saat yang bersamaan.Sebagai contoh:
Komponen:
Menjaga:
Rute:
Modul:
CATATAN : Seperti yang ditunjukkan oleh @JasperRisseeuw, IE dan Edge menangani
beforeunload
acara secara berbeda dari browser lain dan akan menyertakan katafalse
dalam dialog konfirmasi saatbeforeunload
acara diaktifkan (misalnya, browser menyegarkan, menutup jendela, dll.). Menavigasi dalam aplikasi Angular tidak terpengaruh dan akan menampilkan pesan peringatan konfirmasi yang Anda tunjuk dengan benar. Mereka yang perlu mendukung IE / Edge dan tidak inginfalse
menampilkan / menginginkan pesan yang lebih mendetail di dialog konfirmasi saatbeforeunload
acara diaktifkan mungkin juga ingin melihat jawaban @ JasperRisseeuw untuk mengatasinya.sumber
@Injectable()
ke kelas PendingChangesGuard. Juga, saya harus menambahkan PendingChangesGuard ke penyedia saya di@NgModule
import { HostListener } from '@angular/core';
beforeunload
. Jika Anda mengembalikan Observable, itu tidak akan berfungsi. Anda mungkin ingin mengubah antarmuka Anda untuk sesuatu seperticanDeactivate: (internalNavigation: true | undefined)
dan memanggil komponen Anda seperti ini:return component.canDeactivate(true)
. Dengan cara ini, Anda dapat memeriksa apakah Anda tidak menavigasi secara internal untuk kembalifalse
alih-alih Observable.Contoh dengan @Hostlistener dari stewdebaker bekerja dengan sangat baik, tetapi saya membuat satu perubahan lagi karena IE dan Edge menampilkan "false" yang dikembalikan oleh metode canDeactivate () pada kelas MyComponent kepada pengguna akhir.
Komponen:
sumber
false
ditampilkan di dialog konfirmasi. Saya membuat sedikit pengeditan pada jawaban Anda untuk menyertakan'$event'
dalam@HostListener
anotasi, karena itu diperlukan agar dapat mengaksesnya dalamunloadNotification
fungsi.Saya telah mengimplementasikan solusi dari @stewdebaker yang bekerja dengan sangat baik, namun saya menginginkan popup bootstrap yang bagus daripada konfirmasi JavaScript standar yang kikuk. Dengan asumsi Anda sudah menggunakan ngx-bootstrap, Anda dapat menggunakan solusi @ stwedebaker, tetapi tukar 'Guard' dengan yang saya tunjukkan di sini. Anda juga perlu memperkenalkan
ngx-bootstrap/modal
, dan menambahkan yang baruConfirmationComponent
:Menjaga
(ganti 'confirm' dengan fungsi yang akan membuka modal bootstrap - menampilkan custom baru
ConfirmationComponent
):confirm.component.html
konfirmasi.component.ts
Dan karena yang baru
ConfirmationComponent
akan ditampilkan tanpa menggunakanselector
dalam template html, itu perlu dideklarasikan dientryComponents
root Andaapp.module.ts
(atau apa pun yang Anda beri nama modul root Anda). Lakukan perubahan berikut untukapp.module.ts
:app.module.ts
sumber
Solusinya lebih mudah dari yang diharapkan, jangan gunakan
href
karena ini tidak ditangani olehrouterLink
direktif penggunaan Angular Routing .sumber
Jawaban Juni 2020:
Perhatikan bahwa semua solusi yang diusulkan hingga saat ini tidak menangani cacat signifikan yang diketahui dengan
canDeactivate
penjaga Angular :Ini telah dibahas di sini , di sini , dan panjang lebar di sini
Silakan lihat solusi saya untuk masalah yang ditunjukkan di sini yang bekerja dengan aman di sekitar masalah ini *. Ini telah diuji di Chrome, Firefox, dan Edge.
* PERHATIAN PENTING : Pada tahap ini, di atas akan menghapus riwayat maju ketika tombol kembali diklik, tetapi mempertahankan riwayat belakang. Solusi ini tidak akan sesuai jika mempertahankan riwayat maju Anda sangat penting. Dalam kasus saya, saya biasanya menggunakan strategi perutean detail utama ketika datang ke formulir, jadi mempertahankan riwayat ke depan tidak penting.
sumber