App.settings – o caminho angular?

Eu quero adicionar uma seção de App Settings em meu aplicativo onde ele irá conter alguns consts e valores pré-definidos.

Eu já li essa resposta que usa o OpaqueToken mas ela está obsoleta no Angular. Este artigo explica as diferenças, mas não forneceu um exemplo completo e minhas tentativas não tiveram êxito.

Aqui está o que eu tentei (não sei se é o caminho certo):

 //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('apiUrl'); 

E este é o componente onde eu quero usar esses consts:

 //MainPage.ts import {...} from '@angular/core' import {ServiceTest} from "./ServiceTest" @Component({ selector: 'my-app', template: ` Hi ` , providers: [ { provide: ServiceTest, useFactory: ( apiUrl) => { // create data service }, deps: [ new Inject(API_URL) ] } ] }) export class MainPage { } 

Mas isso não funciona e eu recebo erros.

Questão:

Como posso consumir “app.settings” valores do modo Angular?

plunker

NB Claro que posso criar serviço injetável e colocá-lo no provedor do NgModule, mas como eu disse eu quero fazer isso com InjectionToken , do jeito Angular.

Eu descobri como fazer isso com o InjectionTokens (veja o exemplo abaixo), e se seu projeto foi construído usando o Angular CLI você pode usar os arquivos de ambiente encontrados em /environments para application wide settings estáticas do application wide settings como um endpoint da API, mas dependendo do projeto. requisitos você provavelmente acabará usando ambos, pois os arquivos de ambiente são apenas literais de object, enquanto uma configuração injetável usando InjectionToken pode usar as variables ​​de ambiente e uma class pode ter lógica aplicada para configurá-lo com base em outros fatores no aplicativo. como dados iniciais de solicitações http, subdomínio, etc.

Exemplo de Tokens de Injeção

/app/app-config.module.ts

 import { NgModule, InjectionToken } from '@angular/core'; import { environment } from '../environments/environment'; export let APP_CONFIG = new InjectionToken('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 { } 

Agora você pode apenas digitá-lo em qualquer componente, serviço, etc:

/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); } // ... } 

Você também pode digitar a configuração usando o AppConfig exportado.

Se você estiver usando angular-cli , há ainda outra opção:

O Angular CLI fornece arquivos de ambiente em src/environments (os padrões são environment.ts (dev) e environment.prod.ts (production)).

Note que você precisa fornecer os parâmetros de configuração em todos environment.* arquivos environment.* , por exemplo,

environment.ts :

 export const environment = { production: false, apiEndpoint: 'http://localhost:8000/api/v1' }; 

environment.prod.ts :

 export const environment = { production: true, apiEndpoint: '__your_production_server__' }; 

e usá-los em seu serviço (o arquivo de ambiente correto é escolhido automaticamente):

api.service.ts

 // ... other imports import { environment } from '../../environments/environment'; @Injectable() export class ApiService { public apiRequest(): Observable { const path = environment.apiEndpoint + `/objects`; // ... } // ... } 

Aqui está a minha solução, carrega de .json para permitir mudanças sem reconstruir

 import { Injectable, Inject } from '@angular/core'; import { Http } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import { Location } from '@angular/common'; @Injectable() export class ConfigService { private config: any; constructor(private location: Location, private http: Http) { } async apiUrl(): Promise { let conf = await this.getConfig(); return Promise.resolve(conf.apiUrl); } private async getConfig(): Promise { if (!this.config) { this.config = (await this.http.get(this.location.prepareExternalUrl('/assets/config.json')).toPromise()).json(); } return Promise.resolve(this.config); } } 

e config.json

 { "apiUrl": "http://localhost:3000/api" } 

Aqui estão minhas duas soluções para isso

1. Armazene em arquivos json

Basta criar um arquivo json e entrar no seu componente pelo método $http.get() . Se eu precisasse disso muito baixo, então é bom e rápido.

2. Armazenar usando serviços de dados

Se você deseja armazenar e usar em todos os componentes ou ter grande uso, é melhor usar o serviço de dados. Como isso :

  1. Basta criar uma pasta estática dentro da pasta src/app .

  2. Crie um arquivo chamado fuels.ts na pasta estática. Você pode armazenar outros arquivos estáticos aqui também. Deixe definir seus dados como este. Supondo que você tenha dados de combustíveis.

__

 export const Fuels { Fuel: [ { "id": 1, "type": "A" }, { "id": 2, "type": "B" }, { "id": 3, "type": "C" }, { "id": 4, "type": "D" }, ]; } 
  1. Crie um nome de arquivo static.services.ts

__

 import { Injectable } from "@angular/core"; import { Fuels } from "./static/fuels"; @Injectable() export class StaticService { constructor() { } getFuelData(): Fuels[] { return Fuels; } }` 
  1. Agora você pode disponibilizar isso para cada módulo

basta importar no arquivo app.module.ts como este e mudar em provedores

 import { StaticService } from './static.services'; providers: [StaticService] 

Agora use isso como StaticService em qualquer módulo.

Isso é tudo.