Angular 角度2:烛光防护罩

Angular 角度2:烛光防护罩,angular,angular2-routing,angular2-guards,Angular,Angular2 Routing,Angular2 Guards,我已经创建了一个CanDeactivate guard,它返回一个可观察的,并应用到一个加载在内部嵌套路由器出口中的组件。当一个人试图导航到另一个url时,是否应该调用此防护?我问这个是因为我的情况不是这样 在我的例子中,警卫只会被第一个“不同”的URL调用。让我试着用一个例子来解释它。假设我总是返回false,并尝试从同一组件导航到不同的URL: /A --> guard called /B --> guard called /B --> no navigation and

我已经创建了一个CanDeactivate guard,它返回一个可观察的,并应用到一个加载在内部嵌套路由器出口中的组件。当一个人试图导航到另一个url时,是否应该调用此防护?我问这个是因为我的情况不是这样

在我的例子中,警卫只会被第一个“不同”的URL调用。让我试着用一个例子来解释它。假设我总是返回false,并尝试从同一组件导航到不同的URL:

/A --> guard called
/B --> guard called
/B --> no navigation and no guard called
/A --> guard called
/A -->guard not called and no navigation
这是预期的行为吗

编辑嗯,似乎是这样。我们刚刚构建了一个包含3个组件的小示例,只有在用户第一次尝试导航到特定url时才会调用guard…这真的很奇怪

不管怎样,下面是我使用的代码:

// app.routing
import {NgModule} from "@angular/core";
import {Routes, RouterModule, Route, CanDeactivate, ActivatedRouteSnapshot, 
        RouterStateSnapshot} from "@angular/router";
import { MainComponent } from "./main/main.component";
import { OtherComponent } from "./other/other.component";
import { Other3Component } from "./other3/other3.component";
import {Observable} from "rxjs/observable";
const fallback: Route = {
    path: "**",
    redirectTo: "/main",
    pathMatch: "full"
};
export class Test implements CanDeactivate<MainComponent>{
  canDeactivate(component: MainComponent, route: ActivatedRouteSnapshot, 
            state: RouterStateSnapshot): Observable<boolean> | boolean{
    console.log("in");
    return false;
  }
}
export const rotas: Routes = [
{
    path: "main",
    component: MainComponent,
    canDeactivate: [Test]
},
{
    path: "other",
    component: OtherComponent
},
{
    path: "other3",
    component: Other3Component
},
fallback
];

@NgModule({
 imports: [RouterModule.forRoot(rotas)],
 exports: [RouterModule]
})
export class AppRoutingModule{}
//app.routing
从“@angular/core”导入{NgModule};
导入{Routes,RouterModule,Route,CanDeactivate,ActivatedRouteSnapshot,
RouterStateSnashot}来自“@angular/router”;
从“/main/main.component”导入{MainComponent};
从“/other/other.component”导入{OtherComponent};
从“/other3/other3.component”导入{Other3Component};
从“rxjs/Observable”导入{Observable};
常量回退:路由={
路径:“**”,
重定向到:“/main”,
路径匹配:“已满”
};
导出类测试实现CanDeactivate{
canDeactivate(组件:Main组件,路由:ActivatedRouteSnapshot,
状态:RouterStateSnapshot):可观察的|布尔值{
控制台。登录(“登录”);
返回false;
}
}
导出常数旋转:路由=[
{
路径:“主”,
组件:主组件,
canDeactivate:[测试]
},
{
路径:“其他”,
组件:其他组件
},
{
路径:“其他3”,
组件:其他3组件
},
退路
];
@NGD模块({
导入:[RouterModule.forRoot(rotas)],
导出:[路由模块]
})
导出类AppRoutingModule{}
//app.component.html

主要
其他
其他3

所有内容都是通过angular cli生成的(例如:n g component XXX)。是的,CanDeactivate防护将始终返回false,因此您将无法卸载主组件。所以,当我第一次单击“其他”时,警卫被呼叫。如果再次单击“其他”,则不会调用守卫。但是,如果我单击other3,则会调用卫兵。在我点击其他链接(例如:其他)之前,点击其他3不会真正起作用

这是预期的行为吗?我必须说,我希望我的后卫在每次我点击另一个链接时都会被击中

谢谢


路易斯

该死的,臭虫……给赛尔夫的提示:下次,先检查问题板


我找到了这个解决方案,您将创建一个guard服务,并向要添加此选项的每个组件添加一个candeactivate方法,而不是为每个组件创建一个candeactivate guard,因此首先您必须添加此服务文件“deactivate guard.service.ts”:

现在,在要保护的组件中,添加以下功能:

export class ExampleComponent {
    loading: boolean = false;
    //some behaviour that change the loading value
    canDeactivate() {
        console.log('i am navigating away');
        if (this.loading) {
            console.log('no, you wont navigate anywhere');
            return false;
        }
        console.log('you are going away, goodby');
        return true;
    }
}
您可以看到,变量加载是组件的局部加载。 最后一步是将指令添加到路由模块中的组件:

{ 
  path: 'example', 
  canDeactivate: [DeactivateGuardService],
  component: ExampleComponent 
}

就这样,我希望这能帮上忙,祝你好运。

谢谢,解决方案很好。我有几乎完全相同的代码,但打电话给警卫时,它抱怨组件未定义。在我的组件中,我导入接口,类实现它,方法返回一个布尔值。
DeactivateGuardService
canDeactivate
方法如何获取组件?
export class ExampleComponent {
    loading: boolean = false;
    //some behaviour that change the loading value
    canDeactivate() {
        console.log('i am navigating away');
        if (this.loading) {
            console.log('no, you wont navigate anywhere');
            return false;
        }
        console.log('you are going away, goodby');
        return true;
    }
}
{ 
  path: 'example', 
  canDeactivate: [DeactivateGuardService],
  component: ExampleComponent 
}