所以我有一个名为 AuthService 的身份验证服务。它处理 JWT 身份验证并具有属性 loggedIn。该服务已导入我的应用程序组件中。

在应用程序组件中,我还包含一个导航栏组件,用于显示一些导航。我使用 *ngIf 显示登录按钮或注销按钮以及当前登录的用户。该值由 AuthService 提供。

如果我在导航栏组件中导入 AuthService,一切都会正常。但如果它仅包含在应用程序组件中则不然。我认为 Angular 2 中的导入工作是分层的,我在父级别导入的内容应该在子级别可用。还是我错了?

我认为它应该是这样工作的,但事实并非如此:

// app.component.ts 
 
import { Component } from 'angular2/core'; 
import { ROUTER_DIRECTIVES, RouteConfig } from 'angular2/router'; 
 
import { NavbarComponent } from './navbar.component'; 
import { LoginComponent } from './login.component'; 
import { HomeComponent } from '../+home/index'; 
import { Admin } from '../shared/models/admin.model'; 
import { AuthService } from '../shared/services/auth.service'; 
 
@Component({ 
  selector: 'fac-app', 
  providers: [AuthService, Admin], 
  templateUrl: 'app/components/app.component.html', 
  directives: [ROUTER_DIRECTIVES, NavbarComponent, SecretComponent] 
}) 
@RouteConfig([ 
  { 
    path: '/', 
    name: 'Home', 
    component: HomeComponent, 
    useAsDefault: true 
  }, 
  { 
    path: '/login', 
    name: 'Login', 
    component: LoginComponent 
  }, 
  { 
    path: '/secret', 
    name: 'Secret', 
    component: SecretComponent 
  } 
]) 
export class AppComponent { 
 
  constructor(private authService: AuthService) {} 
 
} 
<小时 />
// navbar.component.ts 
 
import { Component } from 'angular2/core'; 
import {ROUTER_DIRECTIVES} from 'angular2/router'; 
 
@Component({ 
  selector: 'fac-navbar', 
  templateUrl: 'app/components/navbar.component.html', 
  styleUrls: ['app/components/navbar.component.css'], 
  directives: [ROUTER_DIRECTIVES] 
}) 
export class NavbarComponent { 
 
} 
<小时 />
// navbar.component.html 
 
<nav class="navbar navbar-default"> 
  <div class="container-fluid"> 
    <div class="navbar-header"> 
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> 
        <span class="sr-only">Toggle navigation</span> 
        <span class="icon-bar"></span> 
        <span class="icon-bar"></span> 
        <span class="icon-bar"></span> 
      </button> 
      <a class="navbar-brand" href="#">Brand</a> 
    </div> 
 
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> 
      <ul class="nav navbar-nav"> 
        <li class="active"><a [routerLink]="['Home']">Home</a></li> 
        <li><a *ngIf="!authService.loggedIn" [routerLink]="['Login']">Login</a></li> 
        <li><a *ngIf="authService.loggedIn" href="#">Logout</a></li> 
      </ul> 
      <p *ngIf="authService.loggedIn" class="navbar-text navbar-right">Signed in as {{authService.currentUserDisplayName()}}</p> 
    </div><!-- /.navbar-collapse --> 
  </div><!-- /.container-fluid --> 
</nav> 
<小时 />
// auth.service.ts 
 
import { Http, Headers } from 'angular2/http'; 
import { Router } from 'angular2/router'; 
import { Injectable } from 'angular2/core'; 
import { JwtHelper, AuthHttp, AuthConfig, tokenNotExpired } from 'angular2-jwt'; 
import { Admin } from '../models/admin.model'; 
 
@Injectable() 
export class AuthService { 
  token: any; 
  jwtHelper: JwtHelper = new JwtHelper(); 
 
  private loggedIn: boolean = false; 
 
  constructor(private http: Http, private router: Router, private authHttp: AuthHttp, private admin: Admin) { 
    this.loggedIn = tokenNotExpired('auth_token'); 
  } 
 
  saveJwt(jwt: any) { 
    if(jwt) { 
      localStorage.setItem('auth_token', jwt); 
      this.token = localStorage.getItem('auth_token'); 
      this.loggedIn = true; 
    } 
  } 
 
  getJwt() { 
    if(this.isAuth()) { 
      return localStorage.getItem('auth_token'); 
    } 
  } 
 
  deleteJwt() { 
    localStorage.removeItem('auth_token'); 
    this.token = localStorage.getItem('auth_token'); 
  } 
 
  isAuth() { 
    return tokenNotExpired('auth_token'); 
  } 
 
  login(admin: Admin) { 
    var header = new Headers(); 
    header.append('Content-Type', 'application/json'); 
    return this.authHttp.post('http://localhost:4000/api/v1/sessions', JSON.stringify({data: {attributes: { email: admin.email, password: admin.password } }}), { 
      headers: header 
    }); 
  } 
 
  logout() { 
    this.deleteJwt(); 
    this.loggedIn = false; 
    this.router.navigate(['Home']); 
  } 
 
  currentUserDisplayName() { 
    var jwt: any = this.getJwt(); 
    var decodedToken: any = this.jwtHelper.decodeToken(jwt); 
    return decodedToken.displayname; 
  } 
 
} 
<小时 />

这是工作版本:

// navbar.component.ts 
 
import { Component } from 'angular2/core'; 
import {ROUTER_DIRECTIVES} from 'angular2/router'; 
 
import { AuthService } from '../shared/services/auth.service'; 
 
@Component({ 
  selector: 'fac-navbar', 
  templateUrl: 'app/components/navbar.component.html', 
  styleUrls: ['app/components/navbar.component.css'], 
  directives: [ROUTER_DIRECTIVES] 
}) 
export class NavbarComponent { 
  constructor(private authService: AuthService) {  } 
 
} 

请您参考如下方法:

  1. *ngIf="!authService.loggedIn" 等模板中的表达式在组件实例的范围内进行计算。所以,它实际上是 navbarComponentInstance.authService.logged。当您在构造函数中省略 private authService: AuthService 时,navbarComponentInstance.authService 显然是未定义的。

  2. “我在父级别导入的内容应该在子级别可用。”是的,当且仅当您在子构造函数中声明服务属性时,服务实例才可以注入(inject)到子组件中。并且,如果该服务已添加到父组件的 providers 中,请勿将其添加到子组件的 providers 中。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!