我想在我的应用程序中添加一个App Settings节,其中包含一些常量和预定义值.

我已经读过this answer了,它使用OpaqueToken,但是它在Angular 上是不推荐使用的.这article条解释了不同之处,但是它没有提供一个完整的例子,我的try 没有成功.

以下是我try 过的(我不知道这是不是正确的方式):

//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 {


}

但它不起作用,我会收到错误.

Question:

如何以Angular 方式使用"app.settings"值?

plunker

注意:我当然可以创建可注入服务,并将其放在NgModule的提供者中,但正如我所说的,我想用InjectionToken,Angular 的方式来实现.

推荐答案

我知道了如何使用InjectionToken(参见下面的示例)来实现这一点,如果您的项目是使用Angular CLI构建的,那么您可以使用/environments中的环境文件作为静态application wide settings,比如API端点,但根据您项目的要求,您很可能会同时使用这两个文件,因为环境文件只是对象文本,而使用InjectionToken的可注入配置可以使用环境变量,因为它是一个类,所以可以根据应用程序中的其他因素(例如初始http请求数据、子域等)应用逻辑来配置它.

Injection Tokens Example

/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 { }

现在,您只需将其注入任何组件、服务等:

/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键入check配置.

Angular相关问答推荐

为什么当我在父组件中设置数组元素时,Angular重新创建子组件而不是更新它?

Angular 17自定义指令渲染不起作用'

Angular 空变量使用组件之间的共享服务

为什么这个拦截器只在发送事件上触发,而不是在实际响应上触发?

基于另一个控制值显示值的Angular 数组

如果Angular 模块是独立的,为什么我不需要在App模块中使用RouterModule?

我们应该在Angular 从14升级到15的过程中也升级茉莉花和业力相关的依赖吗?

更改物料设计中的复选框勾选 colored颜色

代码优化以删除Angular中的嵌套订阅

如何在Primeng中实现自定义排序

Ngrx Select 器返回部分对象

如何使用来自不同可观测对象的值更新可观测对象

RxJS轮询+使用退避策略重试

使用 RXJS 进行空闲/不活动跟踪

无法使用@ngrx/component-store 在其他组件中获取状态更改值

带有数据的 Angular 模板

无法读取 angular2 中未定义(…)的属性 push

Angularmaterial步进器:禁用标题导航

ngx-toastr,Toast 未在 Angular 7 中显示

Angular:找不到不同的支持对象[object Object]