我有一个角度2应用程序,我需要在每个页面上进行身份验证.所以我已经实现了一个自定义的RouterOutlet来确认我在每次更改页面时都已登录.
@Directive({
selector: 'auth-outlet'
})
export class AuthOutlet extends RouterOutlet {
publicRoutes: any;
private parentRouter: Router;
private authService: AuthService;
constructor(_elementRef: ElementRef,
_loader: DynamicComponentLoader,
_parentRouter: Router,
@Attribute('name') nameAttr: string,
_authService: AuthService) {
super(_elementRef, _loader, _parentRouter, nameAttr);
this.parentRouter = _parentRouter;
this.authService = _authService;
this.publicRoutes = {
'Login': true
};
}
activate(oldInstruction: ComponentInstruction) {
var url = this.parentRouter.lastNavigationAttempt;
console.log('attemping to nav');
if (!this.publicRoutes[url] && !this.authService.loggedIn){
var newInstruction = new ComponentInstruction('Login', [], new RouteData(), Login, false, 1);
return super.activate(newInstruction);
} else {
return super.activate(oldInstruction); …Run Code Online (Sandbox Code Playgroud) 我试图让我的路线参与决心.但它不包含参数,但是当我从组件内部使用activatedRoute时它确实有效.我认为这是因为路线在决心内尚未改变.我如何让它工作?
post.resolve.ts
@Injectable()
export class PostResolver implements Resolve<any> {
slug: any;
constructor(
private activatedRoute: ActivatedRoute,
private memoryService: MemoryService,
) {}
resolve() {
console.log(this.activatedRoute);
this.activatedRoute.params.subscribe(params => {
this.slug = params['slug'];
console.log(this.slug);
return this.memoryService.getPost(this.slug);
})
}
}
Run Code Online (Sandbox Code Playgroud)
app.route.ts
{
path: 'post/:slug',
component: PostComponent,
data: {title: 'Post'},
resolve: {
post: PostResolver
}
},
Run Code Online (Sandbox Code Playgroud) 我在下面的角度2中添加路由是我的app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { Home } from './pages/pages';
import { Dashboard } from './pages/pages';
import {ValidationError} from './validators/validators';
import { AuthService } from './services/services';
import { RouterModule, Routes } from '@angular/router';
const appRoutes: Routes = [
{ path: 'home', component: Home },
];
@NgModule({
imports: [ BrowserModule , ReactiveFormsModule, …Run Code Online (Sandbox Code Playgroud) 该应用程序有一个包含2到3个类别按钮的页面.基本上,按钮单击将拉出每个类别中的项目列表,一旦API获取的数据可用,就应显示该页面.
我已经设计了具有解析API调用的angular 2 app路由,当我们将应用程序功能迁移到angular 4时,我不应该在页面加载时使用微调器阻止整个页面.
当用户点击一个类别时,如果响应被延迟,他可以单击另一个类别.当他向后导航时,他会期望在先前点击的类别中加载数据,但Angular 2/4取消了该路线,因为Navigation ID does not match with the current route
为了更好地理解,请查看下面的plnkr链接. http://embed.plnkr.co/UiyhZWCl63Tfq41WY48q/
同时点击行星和人,观察到只有一个部分载荷和其他部分没有加载数据.如果你做检查,你可以看到NavigationCancel事件被抛出
我试图使用此代码传递一个字符串:
this.router.navigate(['/systems', params.toString()]);
Run Code Online (Sandbox Code Playgroud)
然后将route参数附加到API调用的URL.该params.toString()是change_user=2258.但是,当它通过浏览器发送时,它将更改为change_user%3D2558URL.当我使用开发人员工具查看发送给API的内容时,它已更改为NaN.
如何通过路由器传递字符串,以便我可以直接将其附加到我的API字符串?
编辑:变量params是类型URLSearchParams().这就是我试图提取参数的方式:
this.route.paramMap.switchMap((params: ParamMap) =>
this.httpService.getSites(+params.get('params')))
.subscribe(sites => this.sites = sites);
Run Code Online (Sandbox Code Playgroud) 我有canActivate: [ AuthGuard ]里面的路由器和验证AuthGuard
如何强制检查canActivate相同的路由器URL?
例如:当前路线是/admin,我有事件喜欢session expired.我有会话签入,AuthGuard但只有在我执行时才会激活此检查.navigate(...).如何强制canActivate在同一地点运行?
我试过了:this.router.navigate([ this.router.url ]);但角度检查相同的位置,什么都不做.
ps我可以找到"登录页面"或其他页面session expired event,但我有所有重定向内部AuthGuard,我不想在所有其他事件中重复相同的重定向,我只需要location.reload()在Angular2路线中.
主要问题听起来像:如何强制canActivate在当前位置重新运行警卫?
如果我使用延迟加载并为"CanLoad"定义了一个保护.是否需要"CanActivate"?因为可以有效地加载模块但是然后用户做了使"CanLoad"无效的事情,但是因为它被加载,所以用户可以通过CanLoad.
我试图与嵌套的路由器插座进行延迟加载工作,但没有运气.
Angular 4中是否支持此功能?
这是我的用例:
使用延迟加载模块的路由器导航时似乎存在问题.如果我删除延迟加载,这工作正常.但根据延迟加载模块,这是我的设置:
在我的app.template中,我定义了主路由器插座.
我有以下根应用程序路由器
export const ROUTES: Routes = [
{
path: 'user/:id', loadChildren: './user/profile/profile.module#ProfileModule'
}
]
Run Code Online (Sandbox Code Playgroud)
当配置文件模块加载到主路由器插座时,它将显示一个带有两个路由选项卡和内部配置文件的页面.模块我定义了以下子路由
const ROUTES: Routes = [
{
path: '', component: ProfileComponent,
children: [
{ path: 'subPath1', loadChildren: '../subModule1/subModule1.module#SubModule1Module' },
{ path: 'subPath2', loadChildren: '../subModule2/subModule2.module#SubModule2Module' },
]
}
];
@NgModule({
imports: [
RouterModule.forChild(ROUTES),
....
]
}
Run Code Online (Sandbox Code Playgroud)
在profile.template里面我有像这样定义的路由选项卡
<nav md-tab-nav-bar>
<a class="tab-label" md-tab-link [routerLink]="'subPath1'" routerLinkActive #rla="routerLinkActive" [active]="rla.isActive">
Sub path 1
</a>
<a class="tab-label" md-tab-link [routerLink]="'subPath2'" routerLinkActive #rla="routerLinkActive" [active]="rla.isActive">
Sub path 2
</a> …Run Code Online (Sandbox Code Playgroud) 我刚刚开始潜入Angular 1.5来自Angular 1.5.我正在处理用户路由并将API数据从服务中提取到用户组件中.
与1.*中的控制器不同,组件似乎保持静态,在每个请求中刷新它们.
无论如何要在每个新路由请求上调用ngOnInit函数吗?
我的用户组件类:
// url structure: /user/:id
export class UserComponent implements OnInit {
constructor(private route: ActivatedRoute) {}
ngOnInit() {
// doesn't log new id on route change
let id = this.route.snapshot.params['id'];
console.log(id);
this.route.params
.switchMap(params => this.userService.getUser(params['id']))
.subscribe(user => {
// logs new id on route change
let id = this.route.snapshot.params['id'];
console.log(id);
this.user = user
});
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
找到了一个我觉得最适合我的方案的解决方案.根据我的问题和进一步调查的几个答案和评论,订阅路线似乎是要走的路.这是我更新的组件:
export class UserComponent {
user;
id;
constructor(
private userService: UserService,
private route: ActivatedRoute
) {}
ngOnInit() { …Run Code Online (Sandbox Code Playgroud) 我订阅了路由器事件angular2,当我控制事件时,我发现了一个NavigationCancel事件reason: "".很想知道NavigationCancel触发的原因是什么.不仅empty有理由,而且一般.