typescript - Angular 6'da bir kullanıcının form verilerini kaybetmesini önlemek için nasıl bir guard yazılır?


Angular 6 uygulamamda, kullanıcıyı formu kısmen doldurmuş bir şekilde site içinde formdan ayrılmadan önce onaylamalarını isteyerek yönlendirmeyi engelleyecek bir guard oluşturmak istiyorum (tarayıcıyı kapatma veya sayfayı yenileme değil).

Korumamı nasıl oluşturabilirim, böylece bunu rotalarıma uygulayabilir ve kullanıcının kirli bir formdan yanlışlıkla ayrılmasını önleyebilirim?

Formu guard bileşenine enjekte etmeye çalışıyorum, kirli olup olmadığını gözlemlemek istiyorum ve eğer öyleyse, o guard'ı diğer herhangi bir route'a uygulamak ve kullanıcıdan bunlara yönelmeden önce onay almalarını sağlamak istiyorum. Bu, ulaşabildiğim kadar yakın bir yaklaşım, herhangi bir yardım çok takdir edilir.

Şu ana kadar sahip olduklarım şunlar:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
import { NgForm } from "@angular/forms";
import { createMPForm } from "../components/site-settings/site-settings.component"

@Injectable({
  providedIn: 'root'
})

@Injectable()
export abstract class FormGuard implements CanActivate {
  abstract get form(): NgForm;
  formDirty(): boolean {
     return createMPForm.dirty
  }

  constructor() { }

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    if (this.formDirty()) {
      if (confirm("You have unsaved changes! If you leave, your changes will be lost.")) {
        return true;} 
      else {
        return false;}
    }
  }
}

Form bileşenimde bunu ekledim, böylece form nesnesi koruma tarafından içe aktarılabilir:

export class createMPForm {
   @ViewChild("createMPForm", {read: ElementRef}) form: ElementRef;
 }

ve benim rotalarım şöyle görünüyor:

import { FormGuard } from './services/form-guard.service';
import { SiteSettingsComponent } from './components/site-settings/site-settings.component';
import { SiteComponent } from './components/site/site.component';
import { AuthGuard } from './services/auth-guard.service';

const routes: Routes = [
  { path: 'sites', component: SitesComponent, canActivate: [AuthGuard] }, //the route I want to keep from navigating to if the form is dirty
  { path: 'site-settings/:siteHid', component: SiteSettingsComponent, canActivate: [AuthGuard] }// the route with the form
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [AuthGuard, FormGuard]
})

Cevap #1

Aradığınız şey bir CanDeactivate bekçisidir. Bu, bir rotadan ayrılmadan önce çağrılacak bir bekçidir ve mevcut rotanın render ettiği bileşenle birlikte sağlanır.

Bunu şöyle bir şey olarak uygulayabilirsiniz:

interface FormComponent {
  hasUnsavedChanges: boolean
}

class FormGuard implements CanDeactivate<FormComponent> {
  canDeactivate(component: FormComponent) {
    return component.hasUnsavedChanges === false
  }
}

ref: https://angular.io/api/router/CanDeactivate

İlgili makaleler