typescript angular 2 显示/隐藏路由器插座并重定向到 html 页面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40848062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:02:39  来源:igfitidea点击:

angular 2 show/hide router-outlet and redirect to html page

javascriptauthenticationangulartypescript

提问by Kamran Pervaiz

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.

我创建了一个简单的应用程序。我有位于不同域的 AD windows 身份验证 web api,所以我启用了 cors。我创建了一个 api 峰值并在未经授权时返回 401。

app.service.ts

应用服务.ts

authenticateUser(): Observable<any> {
        return this.http.get("http://localhost:36655/", { withCredentials: true })
            .map(this.extractData)
            .catch(this.handleError);
    }

app.component.ts

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
  1. 如何隐藏路由器插座(原因是我不想显示我的主页/链接)
  2. 我可以在主 div 上使用 [hidden] 隐藏它,但是如何重定向?因为<router-outlet></router-outlet>会隐形

app.component.html

应用程序组件.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')?

router.navigate('../shared/contact.html')?

Edit 1:

编辑1:

app.component.ts

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

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

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

应用程序组件.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

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

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.

我可以很好地隐藏菜单,但是 homeComponent 在身份验证之前呈现搜索文本框,我想隐藏所有内容,只想显示徽标。不应显示此对工厂文本框的搜索,底部有像 gridview 之类的数据,我没有在这张图片中显示。

enter image description here

在此处输入图片说明

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

在单击取消之前它不会重定向......另一个解决方案就像我隐藏了菜单我在 homeComponent 上做的但是有很多 authService 调用四处走动,我猜这并不优雅

回答by Dinesh Thamby

In Angular 2 Routes you have 'CanActivate' and 'CanActivateChild' property. This can be used for authorization before rendering the component.

在 Angular 2 Routes 中,您有 'CanActivate' 和 'CanActivateChild' 属性。这可用于在呈现组件之前进行授权。

You can find the usage here: https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard

你可以在这里找到用法: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.
  1. <router-outlet></router-outlet>在您的 app.component.html 中添加。
  2. 提供2条路线

    1. 需要授权的主要组件的默认路由。
    2. 与 contact.html 链接的联系人组件的单独路由(/contact)。

      在 app 模块中导入 RouterModule 来添加路由。
      例子:

      RouterModule.forRoot([
      {
          path: '',
          canActivate: [AuthGuard] //provide the Injectable class here to authenticate.
          component: MainComponent
      },
      {
          path: 'contact',
          component: ContentComponent
      }
      ])
  3. 创建一个@Injectable 类作为对用户进行身份验证的守卫。这将调用应用服务来验证用户并在未经授权的情况下重定向到联系组件。您可以this.router.navigate(['contact']);从“@angular/router”使用导入路由器

  4. 添加这个新的 @Injectable 类作为默认路由的 CanActivate 属性。