Как написать защиту, чтобы пользователь не потерял данные формы в Angular 6? - PullRequest
4 голосов
/ 21 мая 2019

Я хочу создать в моем приложении Angular 6 средство защиты, которое не позволит пользователям переходить от формы на сайте (не закрывая браузер или не обновляя) к частично заполненной форме, прося их подтвердить первый.

Как я могу построить свою защиту, чтобы я мог применить ее к своим маршрутам и предотвратить случайную навигацию пользователя от грязной формы?

Я пытаюсь внедрить форму в компонент защиты, посмотреть, не загрязнена ли она, и, если она есть, применить эту защиту к любому другому маршруту и ​​попросить пользователя подтвердить перед переходом к ним. Это настолько близко, насколько я мог бы, любая помощь будет принята с благодарностью.

Вот что у меня есть:

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;}
    }
  }
}

В моем компоненте формы у меня есть это, так что объект формы может быть импортирован охранником:

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

и мои маршруты выглядят примерно так:

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]
})

1 Ответ

1 голос
/ 21 мая 2019

То, что вы ищете, это защита CanDeactivate.Это средство защиты, которое будет вызываться перед удалением от маршрута и обеспечено компонентом, который отображает текущий маршрут.

Вы можете реализовать это примерно так:

interface FormComponent {
  hasUnsavedChanges: boolean
}

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

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

...