维护产生的令牌用于注射时的服务



我正在创建一个服务来生成随机令牌并将其传递给请求(在开发人员Spotify中,他们强烈建议您这样做(。有一个查询参数(状态(!

这是我的服务:

import { Injectable } from '@angular/core';
@Injectable()
export class TokenService {
    private _state: string;
    constructor() {
        alert('Token got created');
    }
    public get state(): string {
        return this._state;
    }
    generateToken() {
        this._state = this.randomString() + this.randomString();
        alert(this._state);
    }
    private randomString() {
        return Math.random().toString(36).substring(2);
    }
}

我在这里打电话:

...
@Injectable()
export class AngularSpotifyService { 
...
constructor(private windowRef: WindowService, private token: TokenService) { }
getToken(windowName = this.name, windowOptions = this.getOptions()) {
    this.windowRef.nativeWindow.open(`https://accounts.spotify.com/authorize?${this.toQueryString()}`,
      windowName, windowOptions);
}
private toQueryString(): string {
    this.token.generateToken();
    return `client_id=${this.clientId}&response_type=${this.responseType}&redirect_uri=${this.redirectUri}&state=${this.token.state}`;
}

当启动应用程序以及Spotify的响应到达时,这两个服务将得到两次创建。

预期行为:我正在生成一个随机字符串来填充状态查询参数。当响应到达时,我期望令牌服务不会再次创建(我认为是正常行为(,因为如果是正常行为(,它将生成一个新的随机字符串,然后是状态查询参数(再次使用Spotify响应不变。

这是我的app.module:

...
@NgModule({
  declarations: [
      AppComponent,
      TokenComponent,
      AngularSpotifyComponent
  ],
  imports: [
      BrowserModule,
      RouterModule.forRoot(appRoutes)
  ],
  providers: [WindowService, AngularSpotifyService, TokenService],
  exports: [ RouterModule ],
  bootstrap: [AppComponent]
})
export class SpotifyModule { }

您可以在类/服务中通过静态属性("对象初始化"(进行此操作。我做了这个plunkr来演示。

,但它的症结在于,变量声明是在构造函数之外完成的,并且在类的"旋转"时间内计算,从而多次实例化它不会影响值。

export class Example{
  static value: string = Math.random().toString(36).substring(2);
  constructor(){
    console.log(Example.value);
  }
  public getValue(){
    return Example.value;
  }
}
this.example1 = new Example();
this.example2 = new Example();

// NOW!
this.example1.getValue() == this.example2.getValue()

所以只是为了澄清我要提出的观点...

private _state: string;替换为上面的类,然后在先前使用_state的任何地方使用example.getValue()

,新服务看起来像:

@Injectable()
export class TokenService {
    private example: Example;
    constructor() {
        this.example = new Example();
        alert('Token got created');
    }
    public get state(): string {
        return this.example.getValue();
    }
}

显然,您可能会将示例类重命名为您发现合适的任何内容。

最新更新