打字稿:为什么在这种情况下有必要?

时间:2018-03-23 23:14:00

标签: typescript getter-setter

我正在关注this auth0 tutorial.在这个特定的服务中,只有一种方法可以在它前面。

我读了这篇answer和一些教程,但在这个特殊情况下,它确实没有澄清任何内容。

据我了解,getter与setter一起使用,因此您可以阻止修改某些类成员,如:

Class Whatever{

// don't modify the original, only the instance members
private myNum: Number; 

//set the instance member
set myNum(aNum:Number){ 
   this.myNum = aNum;
}

//and now you can get it
get myNum(){
 return this.myNum
}

}

但是我已经搜索了整个教程,但找不到这个getter的解释。无论如何,这是代码(它是最后一个方法,tokenValid():

@Injectable()
export class AuthService {
  // Create Auth0 web auth instance
  private _auth0 = new auth0.WebAuth({
    clientID: AUTH_CONFIG.CLIENT_ID,
    domain: AUTH_CONFIG.CLIENT_DOMAIN,
    responseType: 'token',
    redirectUri: AUTH_CONFIG.REDIRECT,
    audience: AUTH_CONFIG.AUDIENCE,
    scope: AUTH_CONFIG.SCOPE
  });
  userProfile: any;
  isAdmin: boolean;
  // Create a stream of logged in status to communicate throughout app
  loggedIn: boolean;
  loggedIn$ = new BehaviorSubject<boolean>(this.loggedIn);

  constructor(private router: Router) {
    // If authenticated, set local profile property
    // and update login status subject.
    // If not authenticated but there are still items
    // in localStorage, log out.
    const lsProfile = localStorage.getItem('profile');

    if (this.tokenValid) {
      this.userProfile = JSON.parse(lsProfile);
       this.isAdmin = localStorage.getItem('isAdmin') === 'true';
      this.setLoggedIn(true);
    } else if (!this.tokenValid && lsProfile) {
      this.logout();
    }
  }

  setLoggedIn(value: boolean) {
    // Update login status subject
    this.loggedIn$.next(value);
    this.loggedIn = value;
  }

  login() {
    // Auth0 authorize request
    this._auth0.authorize();
  }

  handleAuth() {
    // When Auth0 hash parsed, get profile
    this._auth0.parseHash((err, authResult) => {
      if (authResult && authResult.accessToken) {
        window.location.hash = '';
        this._getProfile(authResult);
      } else if (err) {
        console.error(`Error authenticating: ${err.error}`);
      }
      this.router.navigate(['/']);
    });
  }

  private _getProfile(authResult) {
    // Use access token to retrieve user's profile and set session
    this._auth0.client.userInfo(authResult.accessToken, (err, profile) => {
      if (profile) {
        this._setSession(authResult, profile);
      } else if (err) {
        console.error(`Error authenticating: ${err.error}`);
      }
    });
  }

  private _setSession(authResult, profile) {
    // Save session data and update login status subject
    const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + Date.now());
    // Set tokens and expiration in localStorage and props
    localStorage.setItem('access_token', authResult.accessToken);
    localStorage.setItem('expires_at', expiresAt);
    localStorage.setItem('profile', JSON.stringify(profile));
    this.userProfile = profile;
    // Update login status in loggedIn$ stream

    this.isAdmin = this._checkAdmin(profile);
        localStorage.setItem('isAdmin', this.isAdmin.toString());
    this.setLoggedIn(true);
  }

  private _checkAdmin(profile) {
      // Check if the user has admin role
      const roles = profile[AUTH_CONFIG.NAMESPACE] || [];
      return roles.indexOf('admin') > -1;
    }


  logout() {
    // Ensure all auth items removed from localStorage
    localStorage.removeItem('access_token');
    localStorage.removeItem('profile');
    localStorage.removeItem('expires_at');
    localStorage.removeItem('authRedirect');
     localStorage.removeItem('isAdmin');
    // Reset local properties, update loggedIn$ stream
    this.userProfile = undefined;
     this.isAdmin = undefined;
    this.setLoggedIn(false);
    // Return to homepage
    this.router.navigate(['/']);
  }

/////////HERE IT IS

      get tokenValid(): boolean {
        // Check if current time is past access token's expiration
        const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
        return Date.now() < expiresAt;
  }

}

2 个答案:

答案 0 :(得分:1)

注意没有二传手。在没有setter的情况下创建一个getter是一个很好的方法,可以使一个只读属性不受外部修改的影响。

答案 1 :(得分:0)

您不能拥有2个同名的媒体资源。 所以你可以为私人成员使用下划线。

class Whatever {

  constructor(private _myNum: Number) {
  }

  set myNum(aNum: Number) {
    this._myNum = aNum;
  }

  get myNum() {
    return this._myNum
  }
}

如果您需要使用后代类来进行Whatever, 并且需要覆盖一个方法(获取或设置),你需要 覆盖两者。

看看它是如何在javascript中工作的。 https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty