Voglio aggiungere una sezione App Settings
nella mia app in cui conterrà alcune funzioni e valori predefiniti.
Ho già letto questa risposta che utilizza OpaqueToken
ma è deprecato in Angular. Questo articolo spiega le differenze ma non ha fornito un esempio completo e i miei tentativi non hanno avuto successo.
Ecco cosa ho provato (non so se è il modo giusto):
//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 questo è il componente in cui voglio usare quei comandi:
//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 { }
Ma non funziona e ottengo errori.
Domanda:
Come posso consumare “app.settings” valori in modo angular?
plunker
NB Certo che posso creare il servizio Injectable e metterlo nel provider di NgModule, ma come ho detto, voglio farlo con InjectionToken
, la modalità Angolare.
Ho capito come fare questo con InjectionTokens (vedi esempio sotto), e se il tuo progetto è stato costruito usando la Angular CLI
puoi usare i file di ambiente trovati in /environments
per application wide settings
statiche application wide settings
come un endpoint API, ma a seconda del tuo progetto i requisiti molto probabilmente finiranno per utilizzare entrambi, poiché i file di ambiente sono solo oggetti letterali, mentre una configurazione iniettabile che utilizza InjectionToken
può utilizzare le variabili di ambiente e dato che è ansible applicare a una class una logica per configurarla in base ad altri fattori nell’applicazione, come dati di richiesta HTTP iniziale, sottodominio, ecc.
Esempio di token di iniezione
/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 { }
Ora puoi semplicemente immetterlo in qualsiasi componente, servizio, ecc.
/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); } // ... }
È quindi ansible digitare anche controllare la configurazione utilizzando AppConfig esportato.
Se stai usando angular-cli , c’è ancora un’altra opzione:
La CLI angular fornisce file di ambiente in src/environments
(quelli di default sono environment.ts
(dev) e environment.prod.ts
(produzione)).
Si noti che è necessario fornire i parametri di configurazione in tutti environment.*
file environment.*
, Ad es.
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 usali nel tuo servizio (il file dell’ambiente corretto viene scelto automaticamente):
api.service.ts
// ... other imports import { environment } from '../../environments/environment'; @Injectable() export class ApiService { public apiRequest(): Observable { const path = environment.apiEndpoint + `/objects`; // ... } // ... }
Ecco la mia soluzione, carica da .json per consentire modifiche senza ricostruzione
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" }
Ecco le mie due soluzioni per questo
1. Archiviare in file json
Basta creare un file JSON e accedere al componente con il metodo $http.get()
. Se avevo bisogno di questo molto basso, allora è buono e veloce.
2. Archivia utilizzando i servizi dati
Se si desidera archiviare e utilizzare in tutti i componenti o con un utilizzo elevato, è preferibile utilizzare il servizio dati. Come questo :
Basta creare una cartella statica nella cartella src/app
.
Crea un file chiamato fuels.ts
nella cartella statica. Qui puoi anche archiviare altri file statici. Lascia definire i tuoi dati in questo modo. Supponendo che tu abbia dati di combustibili.
__
export const Fuels { Fuel: [ { "id": 1, "type": "A" }, { "id": 2, "type": "B" }, { "id": 3, "type": "C" }, { "id": 4, "type": "D" }, ]; }
__
import { Injectable } from "@angular/core"; import { Fuels } from "./static/fuels"; @Injectable() export class StaticService { constructor() { } getFuelData(): Fuels[] { return Fuels; } }`
basta importare nel file app.module.ts in questo modo e cambiare fornitore
import { StaticService } from './static.services'; providers: [StaticService]
Ora usa questo come StaticService
in qualsiasi modulo.
È tutto.