最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - angular 2 showhide router-outlet and redirect to html page - Stack Overflow

programmeradmin1浏览0评论

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);
    }

appponent.ts

@Component({
    moduleId: module.id,
    selector: 'app-root',
    templateUrl: 'appponent.html',
    styleUrls: ['appponent.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

appponent.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:

appponent.ts

@Component({
    moduleId: module.id,
    selector: 'app-root',
    templateUrl: 'appponent.html',
    styleUrls: ['appponent.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);
    }
}

appponent.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: '', ponent: HomeComponent, pathMatch: 'full', canActivate: [AuthGuard]
    },
    { path: 'factory', ponent: FactoryFormComponent, canActivate: [AuthGuard]},
    //...some other
    { path: 'contactus', ponent: 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

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.ponent.ts

@Component({
    moduleId: module.id,
    selector: 'app-root',
    templateUrl: 'app.ponent.html',
    styleUrls: ['app.ponent.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.ponent.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.ponent.ts

@Component({
    moduleId: module.id,
    selector: 'app-root',
    templateUrl: 'app.ponent.html',
    styleUrls: ['app.ponent.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.ponent.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: '', ponent: HomeComponent, pathMatch: 'full', canActivate: [AuthGuard]
    },
    { path: 'factory', ponent: FactoryFormComponent, canActivate: [AuthGuard]},
    //...some other
    { path: 'contactus', ponent: 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

Share Improve this question edited Nov 30, 2016 at 16:19 Kamran Pervaiz asked Nov 28, 2016 at 15:34 Kamran PervaizKamran Pervaiz 1,9415 gold badges24 silver badges44 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

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

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.ponent.html.
  2. Provide 2 routes

    1. Default route for your main ponent which requires authorization.
    2. A separate route(/contact) for your contact ponent 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.
          ponent: MainComponent
      },
      {
          path: 'contact',
          ponent: 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 ponent 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.
发布评论

评论列表(0)

  1. 暂无评论