Lui*_*reu 14 angular2-routing angular2-guards angular
我创建了一个CanDeactivate防护,它返回一个observable,它应用于一个加载在内部嵌套路由器插座中的组件.每当有人试图导航到另一个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
Run Code Online (Sandbox Code Playgroud)
这是预期的行为吗?
编辑好吧,它似乎是.刚刚建立了一个包含3个组件的小样本,只有在用户第一次尝试导航到特定网址时才会调用防护...这真的很奇怪......
无论如何,这是我正在使用的代码:
// 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{}
Run Code Online (Sandbox Code Playgroud)
//app.component.html
<h1>
<a routerLink="/main">Main</a>
<a routerLink="/other">Other</a>
<a routerLink="/other3">Other3</a>
</h1>
一切都是通过angular-cli生成的(例如:ng组件XXX).是的,CanDeactivate后卫将始终返回false,因此您将无法卸载主要组件.所以,当我第一次点击其他时,警卫会被召唤.如果再次点击其他,则不会调用任何警卫.但是,如果我点击其他3,那么警卫就会被调用.在我点击其他链接(例如:其他)之前点击其他3将不会真正做任何事情......
这是预期的行为吗?我必须说,每当我点击另一个链接时,我都希望我的后卫能够被击中...
谢谢.
路易斯
小智 25
我找到了这个解决方案,而不是为每个组件创建一个candeactivate防护,你将创建一个防护服务并为你想要添加此选项的每个组件添加一个candeactivate方法,所以首先你必须添加这个服务文件"deactivate-guard .service.ts":
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你必须在app模块中提供:
providers: [
DeactivateGuardService
]
Run Code Online (Sandbox Code Playgroud)
现在在要保护的组件中,添加功能:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以看到变量加载是组件的本地加载.最后一步是将指令添加到路由模块中的组件:
{
path: 'example',
canDeactivate: [DeactivateGuardService],
component: ExampleComponent
}
Run Code Online (Sandbox Code Playgroud)
就是这样,我希望这很有帮助,祝你好运.
归档时间: |
|
查看次数: |
13105 次 |
最近记录: |