web-dev-qa-db-de.com

Angular 2/4 verhindern, dass der Benutzer die Komponente verlässt, wenn die Änderungen nicht gespeichert werden

Ich habe diese Schnittstelle, die ich benutze, um den Benutzer zu verhindern, um Seite zu verlassen

export interface ComponentCanDeactivate {
  canDeactivate: () => boolean;
}

@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
  canDeactivate(component: ComponentCanDeactivate): boolean {
    return  component.canDeactivate() ?
     //code : //more code
  }
}

In einer meiner Komponenten habe ich den folgenden Code

export class DashboardComponent implements ComponentCanDeactivate{
  @HostListener('window:beforeunload')
  canDeactivate(): boolean {
    return !this.isDirty;
  }

Mein Problem ist, dass meine Komponente -> (Komponente: ComponentCanDeactivate) von PendingChangesGuard immer null ist, sodass ich eine Fehlermeldung erhalte

CanDeactivate () von null kann nicht aufgerufen werden

Ich habe auch dieses Setup in meinem Routing

 path: 'dashboard',
        canDeactivate: [PendingChangesGuard],
        loadChildren: './views/dashboard/dashboard.module#DashboardModule'

Kann mir jemand sagen, was ich falsch mache?

7
user9052661

Das Problem wurde durch verzögertes Laden verursacht

Anstatt dies in Ihrem App-Routing zu haben:

path: 'dashboard',
        canDeactivate: [PendingChangesGuard], <-- causing issue
        loadChildren: './views/dashboard/dashboard.module#DashboardModule'

Sie müssen canDeactive aus dem App-Routing entfernen und in das Modul-Routing verschieben.

const routes: Routes = [
  {
    path: '',
    component: DashboardComponent,
    canDeactivate: [ PendingChangesGuard ]
  }
7
user9052661

Ich implementiere so

Deaktivierungs-Wachdienst.ts

export interface CanComponentDeactivate {
  canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}

@Injectable()
export class DeactivateGuardService implements  CanDeactivate<CanComponentDeactivate>{

  canDeactivate(component: CanComponentDeactivate) {
    return component.canDeactivate ? component.canDeactivate() : true;
  }
}

Component.ts

checkSave(): Promise<boolean> {
    var prom = new Promise<boolean>((resolve, reject) => {
      //check saved change
        if(saved) resolve(true);
        else reject(false);
    });
    return prom;
  }

  canDeactivate(): Promise<boolean> {

    return this.checkSave().catch(function () {
      return false;
    });
  }
1
Dakota

Versuchen Sie in Ihrem PendingChangesGuard, die Komponente selbst einzufügen, nicht die Schnittstelle:

export class PendingChangesGuard implements CanDeactivate<DashboardComponent> {
  constructor() {}
  canDeactivate(component: DashboardComponent): boolean {
  ...
  }

Sie können keine Schnittstelle mit Angular DI einfügen, da Schnittstellen nur TypeScript-Konstrukte sind und nicht im Javascript-Code vorhanden sind, der mit dem Kompilierungsprozess erstellt wurde.

Weitere Informationen finden Sie unter this SO.

0
Fjut