问题
I have this error when I build my CanDeactivateGuard .
Uncaught (in promise): TypeError: component.canDeactivate is not a function
I want to make my CanDeactivateGuard reusable, so it should be generic.
therefor I've built an abstract class which called ComponentCanDeactivate and then extended it in the TreeCanDeactivateGuard.
The CanDeactivateGuard should then implement the interface CanDeactivate.
My Code:
import { HostListener } from '@angular/core';
export abstract class ComponentCanDeactivate {
public abstract canDeactivate(): boolean;
@HostListener('window:beforeunload', ['$event'])
unloadNotification($event: any) {
if (!this.canDeactivate()) {
$event.returnValue = true;
}
}
}
The TreeCanDeactivateGuard :
import { ComponentCanDeactivate } from './canDeactivate/component-can-deactivate';
import { NodeService } from '../tree/node.service';
export abstract class TreeCanDeactivateGuard extends ComponentCanDeactivate {
constructor(private _nodeService: NodeService) {
super();
}
public canDeactivate(): boolean {
if (this._nodeService.treeChangesTracer === false) {
return true;
} else {
return false;
}
}
}
The CanDeactivateGuard:
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { ComponentCanDeactivate } from './component-can-deactivate';
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<ComponentCanDeactivate> {
constructor() { }
canDeactivate(component: ComponentCanDeactivate): boolean {
if (!component.canDeactivate()) {
if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
return true;
} else {
return false;
}
}
return true;
}
}
Routes Module :
const routes: Routes = [
{
path: '', component: TreeComponent, canDeactivate: [CanDeactivateGuard] , runGuardsAndResolvers: 'always',
}]
回答1:
What is TreeCanDeactivateGuard
? It isn't referenced anywhere in your code.
You don't want TreeCanDeactivateGuard
to extend ComponentCanDeactivate
, you want TreeComponent
to extend ComponentCanDeactivate
instead.
Make any component extend ComponentCanDeactivate
and implement canDeactivate
then you'll be able to use the generic guard CanDeactivateGuard
for it.
You could also replace:
if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
return true;
} else {
return false;
}
With: return confirm('You have unsaved changes! If you leave, your changes will be lost.');
回答2:
You can't call an absctact method directly through abstract class. Had to do it through child class. Like
canDeactivate(component: TreeCanDeactivateGuard): boolean {
if (!component.canDeactivate()) {
来源:https://stackoverflow.com/questions/53870294/uncaught-in-promise-typeerror-component-candeactivate-is-not-a-function