Ionic2/Angular2: lee un archivo de configuración personalizado
typescript ionic-framework (2)
Después de leer y leer diferentes soluciones, terminé usando esta implementación hacky. Esperemos que pronto haya una solución agradable y nativa disponible:
import { NgModule } from ''@angular/core'';
import { environment as devVariables } from ''./environment.dev'';
import { environment as testVariables } from ''./environment.test'';
import { environment as prodVariables } from ''./environment.prod'';
export function environmentFactory() {
const location = window.location.host;
switch (location) {
case ''www.example.org'': {
return prodVariables;
}
case ''test.example.org'': {
return testVariables;
}
default: {
return devVariables;
}
}
}
@NgModule({
providers: [
{
provide: ''configuration'',
useFactory: environmentFactory
}
]
})
export class EnvironmentsModule {}
y luego donde sea necesario, por ejemplo:
import { Injectable, Injector, Inject } from ''@angular/core'';
import { AuthenticationService } from ''../authentication'';
@Injectable()
export class APIService {
private http: Http;
private apiURL: string;
protected authentication: AuthenticationService;
constructor(
public injector: Injector,
@Inject(''configuration'') public configuration: any
) {
this.http = injector.get(Http);
this.authentication = injector.get(AuthenticationService);
this.apiURL = configuration.apiURL;
};
...
Estoy trabajando en un proyecto ionic2 y necesito crear un nuevo archivo de configuración JSON personalizado. Encontré algunos tutoriales para crear uno y acceder a él a través de http.get, pero creo que es extraño llamarlo a través de una solicitud de obtención. Lo quiero en la carpeta raíz (donde están todos los JSON de configuración) y abro / leo el archivo directamente.
No sé si es posible, o incluso recomendado. Es por eso que estoy publicando aquí para tener algunas opiniones y soluciones :)
Gracias
Personalmente, no me gusta leer el archivo config.json usando la forma http.get para manejar la información de configuración, y aunque debe haber otra forma de incluir y leer el archivo json en su código, ya que estamos usando Angular2 y Typecript, ¿por qué no usar clases, interfaces y hacerlo de una manera más elegante?
Lo que le mostraré a continuación puede parecer más complicado de lo que debería ser al principio (aunque después de leerlo lo encontrará muy sencillo y fácil de entender), pero cuando comencé a aprender Angular2, vi un ejemplo de cómo manejaban los archivos de configuración en la guía de Inyección de dependencias y la seguí en las aplicaciones en las que he trabajado para manejar la información de configuración (como puntos finales de API, valores predeterminados, etc.).
Según los documentos:
Dependencias no de clase
[...]
Las aplicaciones a menudo definen objetos de configuración con muchos hechos pequeños (como el título de la aplicación o la dirección de un punto final de API web), pero estos objetos de configuración no siempre son instancias de una clase.
Una solución para elegir un token de proveedor para dependencias que no sean de clase es definir y usar un OpaqueToken
Por lo tanto, necesitaría definir un objeto de configuración con las URL y así sucesivamente, y luego un
OpaqueToken
para poder usarlo al inyectar el objeto con su configuración.
Incluí toda mi configuración en el archivo
app-config.ts
// Although the ApplicationConfig interface plays no role in dependency injection,
// it supports typing of the configuration object within the class.
export interface ApplicationConfig {
appName: string;
apiEndpoint: string;
}
// Configuration values for our app
export const MY_CONFIG: ApplicationConfig = {
appName: ''My new App'',
apiEndpoint: ''http://www...''
};
// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new OpaqueToken(''config'');
Lo que es
OpaqueToken
puede ser confuso al principio, pero es solo una cadena que evitará conflictos de nombres al inyectar este objeto.
Puedes encontrar una publicación increíble sobre esto
here
.
Luego, solo necesita incluirlo en la página que lo necesita así:
import { NavController } from ''ionic-angular/index'';
import { Component, OpaqueToken, Injectable, Inject } from "@angular/core";
// Import the config-related things
import { MY_CONFIG_TOKEN, MY_CONFIG, ApplicationConfig } from ''app-config.ts'';
@Component({
templateUrl:"home.html",
providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }]
})
export class HomePage {
private appName: string;
private endPoint: string;
constructor(@Inject(MY_CONFIG_TOKEN) private config: ApplicationConfig) {
this.appName = config.appName;
this.endPoint = config.apiEndpoint;
}
}
Tenga en cuenta cómo incluirlo en la matriz de
providers
providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }]
Y cómo decirle al inyector cómo debe obtener la instancia del objeto config
@Inject(MY_CONFIG_TOKEN) config: ApplicationConfig
ACTUALIZAR
OpaqueToken
ha quedado en desuso desde v4.0.0 porque no admite información de tipo, utilice
InjectionToken<?>
lugar.
Entonces, en lugar de estas líneas:
import { OpaqueToken } from ''@angular/core'';
// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new OpaqueToken(''config'');
Ahora deberíamos usar
import { InjectionToken } from ''@angular/core'';
// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new InjectionToken<ApplicationConfig>(''config'');