angular 2显示/隐藏router-outlet并重定向到html页面 [英] angular 2 show/hide router-outlet and redirect to html page
问题描述
我创建了一个简单的应用程序。我有AD Windows身份验证web api,它位于不同的域上,因此我启用了cors。我创建了一个api峰值,并在未经授权时返回401.
app.service.ts
authenticateUser():Observable< any> {
返回this.http.get(http:// localhost:36655 /,{withCredentials:true})
.map(this.extractData)
.catch(this.handleError) );
}
app.component.ts
@Component({
moduleId:module.id,
selector:'app -root',
templateUrl:'app.component.html',
styleUrls:['app.component.css']
})
导出类AppComponent {
构造函数(appService:AppService){
appService.authenticateUser()
.subscribe(response => {
//在这里做点什么,因为它不是401
},
error => {
if(error.indexOf(401)> = 0)
console.log(重定向到联系页面)
else {
}
});
}
}
我正在努力解决两件事
- 如何隐藏Router-Outlet(原因是我不想显示我的主页/链接)
- 我可以使用主div上的[hidden]来隐藏它但是我该如何重定向?因为
< router-outlet>< / router-outlet>
将不可见
app.component.html
< div> ;
< nav class =navbar navbar-default>
< div class =container-fluid>
< a class =navbar-brand[routerLink] =['']>主页< / a>
< ul class =nav navbar-nav>
< li>< a [routerLink] =['/ factory']id =factoryname =factory>工厂< / a>< / li>
< li>< a [routerLink] =['/ supplier']id =suppliername =supplier>供应商< / a>< / li>
< li>< a [routerLink] =['/ businessarea']id =businessAreaname =businessArea>营业面积< / a>< / li>
< / ul>
< / div>
< / nav>
< router-outlet>< / router-outlet>
< / div>
我可以访问全部或无权访问身份验证,这就是我不想显示任何内容的原因。是否有像
router.navigate('../ shared / contact.html')
?
编辑1:
app.component.ts
@Component({
moduleId:module .id,
选择器:'app-root',
templateUrl:'app.component.html',
styleUrls:['app.component.css']
})
导出类AppComponent {
private isAuthenticated:boolean = false;
构造函数(private authService:AuthService){
this.authService.authenticateUser()
.subscribe(response => {
if(response.status == 200)
this.isAuthenticated = true;
},
error => {
if(error.indexOf(401)> = 0)
this.isAuthenticated = false;
});
}
}
authguard.ts
@Injectable()
导出类AuthGuard实现CanActivate {
private isActive:boolean = true;
构造函数(private authService:AuthService,private router:Router){
}
canActivate():boolean {
this.authService.authenticateUser()
.subscribe(()=> {},
error => {
if(error.indexOf(401)> = 0){
let link = [' contactus'];
this.router.navigate(link);
this.isActive = false;
}
});
返回this.isActive;
}
}
auth.service。 ts
@Injectable()
导出类AuthService {
构造函数(私人http:Http){
}
authenticateUser():Observable< any> {
返回this.http.get(http:// localhost:5002 / api / v1 / authenticate,{withCredentials:true})
.map(this.extractData)
。赶上(this.handleError);
}
private extractData(响应:响应){
let body = response;
返回正文|| {};
}
private handleError(错误:响应){
let errMsg:string;
if(error instanceof Response){
errMsg =`$ {error.status} - $ {error.statusText || }';
} else {
errMsg = error.toString();
}
返回Observable.throw(errMsg);
}
}
app.component。 html
< div>
< nav class =navbar navbar-default>
< div class =container-fluid>
< a class =navbar-brand[routerLink] =['']> Ethos< / a>
< ul class =nav navbar-nav* ngIf =isAuthenticated>
< li>< a [routerLink] =['/ factory']id =factoryname =factory>工厂< / a>< / li>
< li>< a [routerLink] =['/ supplier']id =suppliername =supplier>供应商< / a>< / li>
< li>< a [routerLink] =['/ businessarea']id =businessAreaname =businessArea>营业面积< / a>< / li>
< / ul>
< / div>
< / nav>
< div>
< router-outlet>< / router-outlet>
< / div>
< / div>
app.routes.ts
const routes:Routes = [
{
path:'',component:HomeComponent,pathMatch:' full',canActivate:[AuthGuard]
},
{路径:'工厂',组件:FactoryFormComponent,canActivate:[AuthGuard]},
//...some其他
{路径:'contactus',组件:ContactUsComponent}
];
AuthenticateController.cs
public HttpResponseMessage Get()
{
返回User.Identity.IsAuthenticated? new HttpResponseMessage(HttpStatusCode.OK):new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
我可以隐藏菜单,但是在搜索文本框之前的homeComponent在认证之前呈现,我想隐藏一切,只想展示Logo。不应该显示对工厂文本框的搜索,并且底部有像gridview这样的数据,我没有在这张图片中显示。
在点击取消之前它不会重定向...另一个解决方案就像我隐藏了我在homeComponent上执行的菜单但是有很多authService调用我想这是不优雅的。
在Angular 2 Routes中你有'CanActivate'和'CanActivateChild'属性。
这可以在渲染组件之前用于授权。
您可以在此处找到用法: https://angular.io/docs/ts/latest/guide/router.html#!#can -activate-guard
在您的情况下,您不必删除路由器插座。
相反:
- 仅添加
<路由器app.component.html中的-outlet>< / router-outlet>
。 -
提供2条路线
- 主要组件的默认路线,需要授权。
-
与contact.html关联的联系人组件的单独路径(/联系人)。
导入应用程序模块中的RouterModule添加路由。
示例:RouterModule.forRoot([
{
路径:'',
canActivate:[AuthGuard] //在这里提供Injectable类进行身份验证。
组件:MainComponent
},
{
路径:'联系',
组件:ContentComponent
}
])
-
创建一个@Injectable类作为保护来验证用户。这将调用应用服务来对用户进行身份验证,并在未经授权的情况下重定向到联系人组件。
您可以使用this.router.navigate(['contact']);
从@ angular / router导入路由器 - 将这个新的@Injectable类添加为默认路由的CanActivate属性。
I have created a simple application. I have AD windows authentication web api which is on different domain so I have enabled cors. I have created a spike of api and returning 401 when not authorized.
app.service.ts
authenticateUser(): Observable<any> {
return this.http.get("http://localhost:36655/", { withCredentials: true })
.map(this.extractData)
.catch(this.handleError);
}
app.component.ts
@Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
constructor(appService: AppService) {
appService.authenticateUser()
.subscribe(response => {
//do something here because its not 401
},
error => {
if (error.indexOf("401") >= 0)
console.log("Redirect to contact page")
else {
}
});
}
}
There are 2 things I am struggling with
- how do I hide Router-Outlet (reason is I don't want to show my main page/links)
- I can hide it using [hidden] on the main div but then how do I redirect? because
<router-outlet></router-outlet>
will be invisible
app.component.html
<div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand" [routerLink]="['']">Home</a>
<ul class="nav navbar-nav">
<li><a [routerLink]="['/factory']" id="factory" name="factory">Factory</a></li>
<li><a [routerLink]="['/supplier']" id="supplier" name="supplier">Supplier</a></li>
<li><a [routerLink]="['/businessarea']" id="businessArea" name="businessArea">Business Area</a></li>
</ul>
</div>
</nav>
<router-outlet></router-outlet>
</div>
I have access all or no-access authentication that's why I dont want to show anything. Is there something like
router.navigate('../shared/contact.html')
?
Edit 1:
app.component.ts
@Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
private isAuthenticated: boolean = false;
constructor(private authService: AuthService) {
this.authService.authenticateUser()
.subscribe(response => {
if (response.status == 200)
this.isAuthenticated = true;
},
error => {
if (error.indexOf("401") >= 0)
this.isAuthenticated = false;
});
}
}
authguard.ts
@Injectable()
export class AuthGuard implements CanActivate {
private isActive: boolean = true;
constructor(private authService: AuthService, private router: Router) {
}
canActivate(): boolean {
this.authService.authenticateUser()
.subscribe(() => {},
error => {
if (error.indexOf("401") >= 0) {
let link = ['contactus'];
this.router.navigate(link);
this.isActive = false;
}
});
return this.isActive;
}
}
auth.service.ts
@Injectable()
export class AuthService {
constructor(private http: Http) {
}
authenticateUser(): Observable<any> {
return this.http.get("http://localhost:5002/api/v1/authenticate", { withCredentials: true })
.map(this.extractData)
.catch(this.handleError);
}
private extractData(response: Response) {
let body = response;
return body || {};
}
private handleError(error: Response) {
let errMsg: string;
if (error instanceof Response) {
errMsg = `${error.status} - ${error.statusText || ''}`;
} else {
errMsg = error.toString();
}
return Observable.throw(errMsg);
}
}
app.component.html
<div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand" [routerLink]="['']">Ethos</a>
<ul class="nav navbar-nav" *ngIf="isAuthenticated">
<li><a [routerLink]="['/factory']" id="factory" name="factory">Factory</a></li>
<li><a [routerLink]="['/supplier']" id="supplier" name="supplier">Supplier</a></li>
<li><a [routerLink]="['/businessarea']" id="businessArea" name="businessArea">Business Area</a></li>
</ul>
</div>
</nav>
<div>
<router-outlet></router-outlet>
</div>
</div>
app.routes.ts
const routes: Routes = [
{
path: '', component: HomeComponent, pathMatch: 'full', canActivate: [AuthGuard]
},
{ path: 'factory', component: FactoryFormComponent, canActivate: [AuthGuard]},
//...some other
{ path: 'contactus', component: ContactUsComponent }
];
AuthenticateController.cs
public HttpResponseMessage Get()
{
return User.Identity.IsAuthenticated ? new HttpResponseMessage(HttpStatusCode.OK) : new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
I can hide the menu fine but homeComponent which is search textbox renders before authentication, I want to hide everything and just want to show Logo. this search for factory textbox should not be displayed and there is data like gridview at the bottom which i am not showing in this picture.
It does not redirect until Cancel is clicked...another solution is just like I hid the menu I do it on homeComponent but there are many authService calls going around which is not elegant i guess
In Angular 2 Routes you have 'CanActivate' and 'CanActivateChild' property. This can be used for authorization before rendering the component.
You can find the usage here: https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
In your case, you do not have to remove the router-outlet.
Instead:
- Add only
<router-outlet></router-outlet>
in your app.component.html. Provide 2 routes
- Default route for your main component which requires authorization.
A separate route(/contact) for your contact component which is linked with the contact.html.
Import RouterModule in app module to add routes.
example:RouterModule.forRoot([ { path: '', canActivate: [AuthGuard] //provide the Injectable class here to authenticate. component: MainComponent }, { path: 'contact', component: ContentComponent } ])
Create an @Injectable class as a guard to authenticate the user. This will call the app service to authenticate the user and redirect to contact component if unauthorized. You can use
this.router.navigate(['contact']);
import Router from "@angular/router"- Add this new @Injectable class as the CanActivate property for your default route.
这篇关于angular 2显示/隐藏router-outlet并重定向到html页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!