angular 2显示/隐藏router-outlet并重定向到html页面 [英] angular 2 show/hide router-outlet and redirect to html page

查看:93
本文介绍了angular 2显示/隐藏router-outlet并重定向到html页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个简单的应用程序。我有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 {

}
});
}
}

我正在努力解决两件事


  1. 如何隐藏Router-Outlet(原因是我不想显示我的主页/链接)

  2. 我可以使用主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



在您的情况下,您不必删除路由器插座。



相反:


  1. 仅添加<路由器app.component.html中的-outlet>< / router-outlet>

  2. 提供2条路线


    1. 主要组件的默认路线,需要授权。

    2. 与contact.html关联的联系人组件的单独路径(/联系人)。



      导入应用程序模块中的RouterModule添加路由。

      示例:

        RouterModule.forRoot([
      {
      路径:'',
      canActivate:[AuthGuard] //在这里提供Injectable类进行身份验证。
      组件:MainComponent
      },
      {
      路径:'联系',
      组件:ContentComponent
      }
      ])



  3. 创建一个@Injectable类作为保护来验证用户。这将调用应用服务来对用户进行身份验证,并在未经授权的情况下重定向到联系人组件。
    您可以使用 this.router.navigate(['contact']); 从@ angular / router导入路由器


  4. 将这个新的@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

  1. how do I hide Router-Outlet (reason is I don't want to show my main page/links)
  2. 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:

  1. Add only <router-outlet></router-outlet> in your app.component.html.
  2. Provide 2 routes

    1. Default route for your main component which requires authorization.
    2. 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
      }
      ])

  3. 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"

  4. Add this new @Injectable class as the CanActivate property for your default route.

这篇关于angular 2显示/隐藏router-outlet并重定向到html页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆