1. ホーム
  2. javascript

[解決済み] App.settings - Angularの方法?

2022-08-13 20:45:23

質問

私は App Settings セクションを追加したいのですが、そこにはいくつかの定数や事前に定義された値が含まれます。

私はすでに この回答 を使用しています。 OpaqueToken しかし、これはAngularでは非推奨です。これは の記事 は違いを説明していますが、完全な例を提供しておらず、私の試みは失敗しました。

以下は、私が試したものです(これが正しい方法かどうかはわかりません)。

//ServiceAppSettings.ts

import {InjectionToken, OpaqueToken} from "@angular/core";

const CONFIG = {
  apiUrl: 'http://my.api.com',
  theme: 'suicid-squad',
  title: 'My awesome app'
};
const FEATURE_ENABLED = true;
const API_URL = new InjectionToken<string>('apiUrl');

そして、これはこれらの定数を使用したいコンポーネントです。

//MainPage.ts

import {...} from '@angular/core'
import {ServiceTest} from "./ServiceTest"

@Component({
  selector: 'my-app',
  template: `
   <span>Hi</span>
  ` ,  providers: [
    {
      provide: ServiceTest,
      useFactory: ( apiUrl) => {
        // create data service
      },
      deps: [

        new Inject(API_URL)
      ]
    }
  ]
})
export class MainPage {


}

でもうまくいかず、エラーが出ます。

質問です。

どのように私はAngularの方法で"app.settings" 値を消費することができますか?

プランカー

NB 確かに私は注入可能なサービスを作成し、NgModuleのプロバイダにそれを置くことができます , しかし、私が言ったように、私はそれを行うためにしたい InjectionToken Angularの方法で。

どのように解決するのですか?

InjectionTokens を使ってこれを行う方法を見つけました (以下の例を参照してください)。 Angular CLI にある環境ファイルを使用することができます。 /environments 静的な application wide settings を使用した注入可能な設定であるのに対し、 環境ファイルは単なるオブジェクトリテラルであるため、 プロジェクトの要件によっては両方を使用することになるでしょう。 InjectionToken を使用した注入可能な設定は環境変数を使用でき、クラスであるため、アプリケーションの他の要因 (最初の http 要求データ、サブドメインなど) に基づいてそれを構成するためにロジックを適用することができます。

インジェクション トークンの例

/app/app-config.module.ts

import { NgModule, InjectionToken } from '@angular/core';
import { environment } from '../environments/environment';

export let APP_CONFIG = new InjectionToken<AppConfig>('app.config');

export class AppConfig {
  apiEndpoint: string;
}

export const APP_DI_CONFIG: AppConfig = {
  apiEndpoint: environment.apiEndpoint
};

@NgModule({
  providers: [{
    provide: APP_CONFIG,
    useValue: APP_DI_CONFIG
  }]
})
export class AppConfigModule { }

/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppConfigModule } from './app-config.module';

@NgModule({
  declarations: [
    // ...
  ],
  imports: [
    // ...
    AppConfigModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

これで、任意のコンポーネントやサービスなどにDIすればよい。

/app/core/auth.service.ts

import { Injectable, Inject } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

import { APP_CONFIG, AppConfig } from '../app-config.module';
import { AuthHttp } from 'angular2-jwt';

@Injectable()
export class AuthService {

  constructor(
    private http: Http,
    private router: Router,
    private authHttp: AuthHttp,
    @Inject(APP_CONFIG) private config: AppConfig
  ) { }

  /**
   * Logs a user into the application.
   * @param payload
   */
  public login(payload: { username: string, password: string }) {
    return this.http
      .post(`${this.config.apiEndpoint}/login`, payload)
      .map((response: Response) => {
        const token = response.json().token;
        sessionStorage.setItem('token', token); // TODO: can this be done else where? interceptor
        return this.handleResponse(response); // TODO:  unset token shouldn't return the token to login
      })
      .catch(this.handleError);
  }

  // ...
}

そして、エクスポートされたAppConfigを使って、コンフィグをタイプチェックすることも可能です。