Definieren Sie globale Konstanten

258

In Angular 1.x können Sie Konstanten wie folgt definieren:

angular.module('mainApp.config', [])
    .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/')

Was wäre das Äquivalent in Angular (mit TypeScript)?

Ich möchte die API-Basis-URL in all meinen Diensten einfach nicht immer wieder wiederholen.

AndreFeijo
quelle

Antworten:

265

Die folgenden Änderungen funktionieren für mich in der endgültigen Version von Angular 2:

export class AppSettings {
   public static API_ENDPOINT='http://127.0.0.1:6666/api/';
}

Und dann im Service:

import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(AppSettings.API_ENDPOINT+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}
AndreFeijo
quelle
Ich denke, deine AppSettingsKlasse sollte abstrakt sein und das API_ENDPOINTMitglied sollte es sein readonly.
Philippe Gioseffi
164

Die Lösung für die vom Winkelteam selbst bereitgestellte Konfiguration finden Sie hier .

Hier ist der gesamte relevante Code:

1) app.config.ts

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

export let APP_CONFIG = new OpaqueToken("app.config");

export interface IAppConfig {
    apiEndpoint: string;
}

export const AppConfig: IAppConfig = {    
    apiEndpoint: "http://localhost:15422/api/"    
};

2) app.module.ts

import { APP_CONFIG, AppConfig } from './app.config';

@NgModule({
    providers: [
        { provide: APP_CONFIG, useValue: AppConfig }
    ]
})

3) your.service.ts

import { APP_CONFIG, IAppConfig } from './app.config';

@Injectable()
export class YourService {

    constructor(@Inject(APP_CONFIG) private config: IAppConfig) {
             // You can use config.apiEndpoint now
    }   
}

Jetzt können Sie die Konfiguration überall einfügen, ohne die Zeichenfolgennamen zu verwenden und Ihre Schnittstelle für statische Überprüfungen zu verwenden.

Sie können natürlich die Schnittstelle und die Konstante weiter trennen, um unterschiedliche Werte in Produktion und Entwicklung liefern zu können, z

Ilya Chernomordik
quelle
3
Es funktioniert nur, wenn ich den Typ im Konstruktor des Dienstes nicht angegeben habe. So funktioniert es, wenn ich Konstruktor (@Inject (APP_CONFIG) private config) {} mache . Dies wird hier erwähnt: blog . Thoughtram.io/angular/2016/05/23/… aber nicht warum.
Mukus
Ich nehme an, Sie haben ein Import- oder Export-Schlüsselwort oder ähnliches verpasst, da ich es mit der Benutzeroberfläche verwende und es, wie Sie sagen, sehr wichtig ist, dass es explizit statisch eingegeben wird. Möglicherweise müssen Sie hier eine genaue Ausnahme angeben.
Ilya Chernomordik
46
Keine dieser Lösungen, selbst der vom eckigen Team empfohlene Ansatz, sieht elegant aus. Warum ist der Versuch, Konstanten zu erstellen, in Angular 2 ein umständlicher Prozess? Kannst du nicht sehen, wie nahtlos Angular1 es geschafft hat? Warum all das Durcheinander?
KhoPhi
31
Für alle anderen, die diese Antwort treffen, ist das OpaqueToken in Angular v4 für InjectionToken "veraltet" - blog.ehowtram.io/angular/2016/05/23/…
mtpultz
3
Wäre es sinnvoll , von dem Code zu setzen Schritt 1 in environment.tsund environment.prod.tsso , dass Sie verschiedene Konstanten pro Umwelt haben können? @IlyaChernomordik begann dies im letzten Absatz seiner Antwort zu erwähnen.
Robert Bernstein
64

In Angular2 haben Sie Folgendes zur Verfügung gestellt Definition, die Ihnen verschiedene Arten von Abhängigkeiten Setup erlaubt:

provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}

Im Vergleich zu Winkel 1

app.servicein Angular1 entspricht useClassin Angular2.

app.factoryin Angular1 entspricht useFactoryin Angular2.

app.constantund app.valuewurde useValuemit weniger Einschränkungen vereinfacht . dh es gibt keinen configBlock mehr.

app.provider - In Winkel 2 gibt es kein Äquivalent.

Beispiele

So richten Sie mit dem Root-Injektor ein:

bootstrap(AppComponent,[provide(API_ENDPOINT, { useValue='http://127.0.0.1:6666/api/' })]);

Oder richten Sie mit dem Injektor Ihrer Komponente ein:

providers: [provide(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})]

provide ist eine Abkürzung für:

var injectorValue = Injector.resolveAndCreate([
  new Provider(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})
]);

Mit dem Injektor ist es einfach, den Wert zu ermitteln:

var endpoint = injectorValue.get(API_ENDPOINT);
Pixelbits
quelle
2
Ich möchte meine Einstellungen tatsächlich in einer externen Datei haben, z. B.: Settings.ts Wie würde diese Datei aussehen?
AndreFeijo
Haben Sie serverseitiges Javascript wie NodeJS in Betracht gezogen?
Pixelbits
5
Entschuldigung, ich habe nicht verstanden, wie ich es in meinen Dienst einspeisen soll? Muss ich eine externe Datei exportieren, da ich sie verwende?
AndreFeijo
Ich würde es zu einem Teil Ihres Build-Konfigurationsprozesses machen. dh basierend auf Ihrer Umgebung verschiedene Dateien zusammen kompilieren / verpacken und dann bereitstellen. All dies können Sie mit NodeJS mit den richtigen Modulen tun.
Pixelbits
1
NodeJS ist leider keine Option.
AndreFeijo
59

In Angular 4 können Sie die Umgebungsklasse verwenden, um alle Ihre globalen Werte beizubehalten.

Sie haben standardmäßig environment.ts und environment.prod.ts.

Beispielsweise

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

Und dann zu Ihren Diensten:

import { environment } from '../../environments/environment';
...
environment.apiUrl;
Nacho
quelle
Wenn Sie versuchen, auf ein constInneres eines Dienstes zuzugreifen , müssen Sie es möglicherweise im Provider-Array Ihres App-Moduls "bereitstellen" : { provide: 'ConstName', useValue: ConstName }. Ich habe ohne dies einen Laufzeitfehler erhalten.
Daleyjem
@daleyjem, weil du versucht hast, es zu injizieren. Dieser Ansatz verwendet nicht den Injektor
Aluan Haddad
Das Erstellen einer solchen Konstante ist am einfachsten. Ich denke, das Gegenargument, DI zu verlieren und dadurch Testbarkeit / mockValue zu verlieren, ist einige Zeit überbewertet. In einer typischen App verwenden wir so viele Nicht-DI-Komponenten wie (RxJS), ohne die Testbarkeit zu beeinträchtigen.
Amitesh
54

Aktualisiert für Angular 4+

Jetzt können wir einfach Umgebungsdateien verwenden, deren Winkel Standard sind, wenn Ihr Projekt über Angular-CLI generiert wird.

beispielsweise

Erstellen Sie in Ihrem Umgebungsordner folgende Dateien

  • environment.prod.ts
  • environment.qa.ts
  • environment.dev.ts

und jede Datei kann verwandte Codeänderungen enthalten, wie zum Beispiel:

  • environment.prod.ts

    export const environment = {
         production: true,
         apiHost: 'https://api.somedomain.com/prod/v1/',
         CONSUMER_KEY: 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
  • environment.qa.ts

    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/qa/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
  • environment.dev.ts

    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/dev/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };

Anwendungsfall in der Anwendung

Sie können Umgebungen in beliebige Dateien wie z. B. Dienste importieren clientUtilServices.ts

import {environment} from '../../environments/environment';

getHostURL(): string {
    return environment.apiHost;
  }

Anwendungsfall im Build

Öffnen Sie Ihre eckige CLI-Datei .angular-cli.jsonund "apps": [{...}]fügen Sie den folgenden Code hinzu

 "apps":[{
        "environments": {
            "dev": "environments/environment.ts",
            "prod": "environments/environment.prod.ts",
            "qa": "environments/environment.qa.ts",
           }
         }
       ]

Wenn Sie für die Produktion erstellen möchten, führen ng build --env=prodSie die Konfiguration aus environment.prod.ts, genauso wie Sie dies für qaoder tun könnendev

## Ältere Antwort

Ich habe in meinem Provider Folgendes getan:

import {Injectable} from '@angular/core';

@Injectable()
export class ConstantService {

API_ENDPOINT :String;
CONSUMER_KEY : String;

constructor() {
    this.API_ENDPOINT = 'https://api.somedomain.com/v1/';
    this.CONSUMER_KEY = 'someReallyStupidTextWhichWeHumansCantRead'
  }
}

Dann habe ich überall Zugriff auf alle konstanten Daten

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';

import {ConstantService} from  './constant-service'; //This is my Constant Service


@Injectable()
export class ImagesService {
    constructor(public http: Http, public ConstantService: ConstantService) {
    console.log('Hello ImagesService Provider');

    }

callSomeService() {

    console.log("API_ENDPOINT: ",this.ConstantService.API_ENDPOINT);
    console.log("CONSUMER_KEY: ",this.ConstantService.CONSUMER_KEY);
    var url = this.ConstantService.API_ENDPOINT;
    return this.http.get(url)
  }
 }
Anjum ....
quelle
6
Dies funktioniert nicht wie eine Konstante. Der Wert einer Konstante ist immer der gleiche. In Ihrem Fall kann Ihr API_ENDPOINTWert jederzeit überschrieben werden. Wenn this.ConstantService.API_ENDPOINT = 'blah blah'in der Klasse jederzeit deklariert wird, nachdem Ihre sogenannte "Konstante" aus dem importiert wurde, lautet constant-serviceder neue Wert von API_ENDPOINT 'blah blah'. Ihre Lösung zeigt nur, wie Sie mit einem Dienst auf eine Variable zugreifen und nicht mit einer Konstanten.
Devner
1
@ Devner machen sie nur schreibgeschütztreadonly API_ENDPOINT :String;
Flavien Volken
@Anjum Wie eckig die env-Dateien auswählt. Sollte ich beim Starten der App den Namen env eingeben müssen?
Begriff Quest
@notionquest Ja, Sie können es bestehen, wieng build --env=prod
Anjum ....
31

Der Ansatz, eine AppSettings-Klasse mit einer Zeichenfolgenkonstante wie ApiEndpoint zu haben, funktioniert zwar, ist jedoch nicht ideal, da wir diesen realen ApiEndpoint zum Zeitpunkt des Komponententests nicht gegen einige andere Werte austauschen können.

Wir müssen in der Lage sein, diese API-Endpunkte in unsere Dienste einzufügen (denken Sie daran, einen Dienst in einen anderen Dienst einzufügen). Wir müssen dafür auch keine ganze Klasse erstellen. Wir möchten lediglich einen String in unsere Dienste einfügen, der unser ApiEndpoint ist. Um die hervorragende Antwort durch Pixelbits zu vervollständigen , finden Sie hier den vollständigen Code, wie dies in Angular 2 durchgeführt werden kann:

Zunächst müssen wir Eckige sagen , wie zu schaffen , eine Instanz unserer ApiEndpoint , wenn wir es in unserer App fragen (man denke an sie als eine Abhängigkeit Registrierung):

bootstrap(AppComponent, [
        HTTP_PROVIDERS,
        provide('ApiEndpoint', {useValue: 'http://127.0.0.1:6666/api/'})
]);         


Und dann injizieren wir diesen ApiEndpoint im Service in den Servicekonstruktor und Angular stellt ihn uns basierend auf unserer obigen Registrierung zur Verfügung:

import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable, Inject} from 'angular2/core';  // * We import Inject here
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http, 
                @Inject('ApiEndpoint') private apiEndpoint: string) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(`${this.apiEndpoint}/messages`)
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    } 
    // the rest of the code...
}
Morteza Manavi
quelle
1
Es gibt jetzt eine "offizielle" Vorgehensweise, die das Angular-Team in seinem Tutorial empfiehlt. Ich habe eine Antwort unten hinzugefügt: ( stackoverflow.com/a/40287063/1671558 )
Ilya Chernomordik
1
Dieser Code ist nicht mehr korrekt. Wenn Sie dies implementieren, wird ein ApiEndpoint nicht in AppComponent gefunden.
WilliamX
Ok, also bin ich nicht alleine. Wissen Sie, welche Version dies brach? Gibt es eine alternative Möglichkeit, bei der keine Werte für ein globales Objekt definiert und dann bereitgestellt werden müssen?
Jens Bodal
29

Dies ist meine jüngste Erfahrung mit diesem Szenario:

  • @ angle / cli: 1.0.0
  • Knoten: 6.10.2
  • @ Winkel / Kern: 4.0.0

Ich habe die offiziellen und aktualisierten Dokumente hier verfolgt:

https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#dependency-injection-tokens

Es scheint, dass OpaqueToken jetzt veraltet ist und wir InjectionToken verwenden müssen. Dies sind also meine Dateien, die wie ein Zauber laufen:

app-config.interface.ts

export interface IAppConfig {

  STORE_KEY: string;

}

app-config.constants.ts

import { InjectionToken } from "@angular/core";
import { IAppConfig } from "./app-config.interface";

export const APP_DI_CONFIG: IAppConfig = {

  STORE_KEY: 'l@_list@'

};

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

app.module.ts

import { APP_CONFIG, APP_DI_CONFIG } from "./app-config/app-config.constants";

@NgModule( {
  declarations: [ ... ],
  imports: [ ... ],
  providers: [
    ...,
    {
      provide: APP_CONFIG,
      useValue: APP_DI_CONFIG
    }
  ],
  bootstrap: [ ... ]
} )
export class AppModule {}

my-service.service.ts

  constructor( ...,
               @Inject( APP_CONFIG ) private config: IAppConfig) {

    console.log("This is the App's Key: ", this.config.STORE_KEY);
    //> This is the App's Key:  l@_list@

  }

Das Ergebnis ist sauber und es gibt keine Warnungen auf der Konsole. Dank des jüngsten Kommentars von John Papa in dieser Ausgabe:

https://github.com/angular/angular-cli/issues/2034

Der Schlüssel wurde in einer anderen Datei der Schnittstelle implementiert.

JavierFuentes
quelle
Siehe auch stackoverflow.com/a/43193574/3092596 - was im Grunde das gleiche ist, aber injizierbare Module anstelle von Anbietern erstellt
am
19

Alle Lösungen scheinen kompliziert zu sein. Ich suche nach der einfachsten Lösung für diesen Fall und möchte nur Konstanten verwenden. Konstanten sind einfach. Gibt es etwas, das gegen die folgende Lösung spricht?

app.const.ts

'use strict';

export const dist = '../path/to/dist/';

app.service.ts

import * as AppConst from '../app.const'; 

@Injectable()
export class AppService {

    constructor (
    ) {
        console.log('dist path', AppConst.dist );
    }

}
Alexander Schmidt
quelle
2
Nun, Sie verwenden Variablen außerhalb des Bereichs des Dienstes, sodass Sie dann auch nur Fensterglobale verwenden können. Wir versuchen, Konstanten in das Angular4-Abhängigkeitsinjektionssystem zu integrieren, damit wir den Bereich sauber, stubbar oder verspottbar halten können.
Joel Hernandez
11

Verwenden Sie einfach eine Typescript-Konstante

export var API_ENDPOINT = 'http://127.0.0.1:6666/api/';

Sie können es im Abhängigkeitsinjektor mit verwenden

bootstrap(AppComponent, [provide(API_ENDPOINT, {useValue: 'http://127.0.0.1:6666/api/'}), ...]);
SnareChops
quelle
1
Warum injizieren? Keine Notwendigkeit dafür, denke ich ... Sie können es verwenden, sobald Sie es importieren. @ SnareChops
Sasxa
@ Sasxa Ich stimme zu, obwohl es gut für Unit-Tests und so sein könnte. Ich versuche nur, eine vollständige Antwort zu geben.
SnareChops
1
@ Andreas Sie könnten constyest verwenden
SnareChops
Bitte geben Sie einen Stackblitz dieser Arbeit an. Ich habe so viele Beispiele für die Bereitstellung eines Dienstes in der Bootstrap-Methode gesehen, aber noch keinen mit einem ausreichend funktionierenden Beispiel gefunden. Möglicherweise hat sich in einer neueren Version von Angular etwas geändert.
Jens Bodal
4

Wenn Sie Webpack verwenden , das ich empfehle, können Sie Konstanten für verschiedene Umgebungen einrichten. Dies ist besonders nützlich, wenn Sie je nach Umgebung unterschiedliche konstante Werte haben.

Sie haben wahrscheinlich mehrere Webpack-Dateien in Ihrem /configVerzeichnis (z. B. webpack.dev.js, webpack.prod.js usw.). Dann haben Sie eine, die custom-typings.d.tsSie dort hinzufügen. Hier ist das allgemeine Muster, das in jeder Datei zu befolgen ist, und eine Beispielverwendung in einer Komponente.

Webpack. {env} .js

const API_URL = process.env.API_URL = 'http://localhost:3000/';
const JWT_TOKEN_NAME = "id_token";
...
    plugins: [
      // NOTE: when adding more properties, make sure you include them in custom-typings.d.ts
      new DefinePlugin({
        'API_URL': JSON.stringify(API_URL),
        'JWT_TOKEN_NAME': JSON.stringify(JWT_TOKEN_NAME)
      }),

custom-typings.d.ts

declare var API_URL: string;
declare var JWT_TOKEN_NAME: string;
interface GlobalEnvironment {
  API_URL: string;
  JWT_TOKEN_NAME: string;
}

Komponente

export class HomeComponent implements OnInit {
  api_url:string = API_URL;
  authToken: string = "Bearer " + localStorage.getItem(JWT_TOKEN_NAME)});
}
gelegentlich
quelle
3

Die Verwendung einer Eigenschaftendatei, die während eines Builds generiert wird, ist einfach und unkompliziert. Dies ist der Ansatz, den die Angular CLI verwendet. Definieren Sie eine Eigenschaftendatei für jede Umgebung und verwenden Sie während der Erstellung einen Befehl, um zu bestimmen, welche Datei in Ihre App kopiert wird. Importieren Sie dann einfach die zu verwendende Eigenschaftendatei.

https://github.com/angular/angular-cli#build-targets-and-environment-files

R.Creager
quelle
3

Ein Ansatz für Angular4 wäre die Definition einer Konstante auf Modulebene:

const api_endpoint = 'http://127.0.0.1:6666/api/';

@NgModule({
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    MessageService,
    {provide: 'API_ENDPOINT', useValue: api_endpoint}
  ]
})
export class AppModule {
}

Dann in Ihrem Dienst:

import {Injectable, Inject} from '@angular/core';

@Injectable()
export class MessageService {

    constructor(private http: Http, 
      @Inject('API_ENDPOINT') private api_endpoint: string) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(this.api_endpoint+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}
Juangui Jordán
quelle
3

Ich habe eine andere Möglichkeit, globale Konstanten zu definieren. Denn wenn wir in der ts-Datei definiert haben, ist es im Build-Modus nicht einfach, Konstanten zu finden, um den Wert zu ändern.

export class SettingService  {

  constructor(private http: HttpClient) {

  }

  public getJSON(file): Observable<any> {
      return this.http.get("./assets/configs/" + file + ".json");
  }
  public getSetting(){
      // use setting here
  }
}

Im App-Ordner füge ich den Ordner configs / settings.json hinzu

Inhalt in settings.json

{
    "baseUrl": "http://localhost:52555"
}

Fügen Sie im App-Modul APP_INITIALIZER hinzu

   {
      provide: APP_INITIALIZER,
      useFactory: (setting: SettingService) => function() {return setting.getSetting()},
      deps: [SettingService],
      multi: true
    }

Auf diese Weise kann ich den Wert in der JSON-Datei einfacher ändern. Ich benutze diesen Weg auch für ständige Fehler- / Warnmeldungen.

Hien Nguyen
quelle
0

AngularJS module.constant definiert keine Konstante im Standard-Sinne.

Während es als Anbieterregistrierungsmechanismus für sich steht, wird es am besten im Kontext der verwandten module.value( $provide.value) Funktion verstanden. In der offiziellen Dokumentation ist der Anwendungsfall klar angegeben:

Registrieren Sie einen Wertedienst beim $ -Injektor, z. B. eine Zeichenfolge, eine Zahl, ein Array, ein Objekt oder eine Funktion. Dies ist die Abkürzung für die Registrierung eines Dienstes, bei dem die Eigenschaft $ get seines Anbieters eine Factory-Funktion ist, die keine Argumente akzeptiert und den Wertedienst zurückgibt. Dies bedeutet auch, dass es nicht möglich ist, andere Dienste in einen Wertedienst einzufügen.

Vergleichen Sie dies mit der Dokumentation für module.constant( $provide.constant), in der auch der Anwendungsfall klar angegeben ist (Hervorhebung von mir):

Registrieren Sie einen konstanten Dienst beim $ -Injektor, z. B. eine Zeichenfolge, eine Zahl, ein Array, ein Objekt oder eine Funktion. Wie der Wert ist es nicht möglich, andere Dienste in eine Konstante einzufügen. Im Gegensatz zum Wert kann eine Konstante in eine Modulkonfigurationsfunktion eingefügt werden (siehe angle.Module) und von einem AngularJS-Dekorator nicht überschrieben werden .

Daher constantliefert die AngularJS- Funktion keine Konstante im allgemein verständlichen Sinne des Begriffs auf dem Gebiet.

Die Einschränkungen für das bereitgestellte Objekt sowie seine frühere Verfügbarkeit über den $ -Injektor lassen jedoch eindeutig darauf schließen, dass der Name analog verwendet wird.

Wenn Sie eine tatsächliche Konstante in einer AngularJS-Anwendung wünschen, würden Sie eine wie in jedem JavaScript-Programm "bereitstellen"

export const π = 3.14159265;

In Winkel 2 ist dieselbe Technik anwendbar.

Angular 2-Anwendungen haben keine Konfigurationsphase im gleichen Sinne wie AngularJS-Anwendungen. Darüber hinaus gibt es keinen Service-Dekorationsmechanismus ( AngularJS Decorator ), was jedoch nicht besonders überraschend ist, da sie sich voneinander unterscheiden.

Das Beispiel von

angular
  .module('mainApp.config', [])
  .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/');

ist vage willkürlich und leicht abstoßend, weil $provide.constantdamit ein Objekt angegeben wird, das übrigens auch eine Konstante ist. Du hättest genauso gut schreiben können

export const apiEndpoint = 'http://127.0.0.1:6666/api/';

für alle kann sich beides ändern.

Jetzt wird das Argument für Testbarkeit, das die Konstante verspottet, verringert, weil es sich buchstäblich nicht ändert.

Man verspottet π nicht.

Natürlich könnte Ihre anwendungsspezifische Semantik darin bestehen, dass sich Ihr Endpunkt ändern könnte oder Ihre API über einen nicht transparenten Failover-Mechanismus verfügt, sodass es unter bestimmten Umständen sinnvoll wäre, den API-Endpunkt zu ändern.

In diesem Fall constanthätte es jedoch nicht funktioniert , es als String-Literal-Darstellung einer einzelnen URL für die Funktion bereitzustellen.

Ein besseres Argument, das wahrscheinlich mit dem Grund für die Existenz der AngularJS- $provide.constantFunktion übereinstimmt , ist, dass JavaScript bei der Einführung von AngularJS kein Standardmodulkonzept hatte . In diesem Fall würden Globals verwendet, um veränderbare oder unveränderliche Werte zu teilen, und die Verwendung von Globals ist problematisch.

Das heißt, wenn so etwas durch ein Framework bereitgestellt wird, erhöht sich die Kopplung an dieses Framework. Es mischt auch winkelspezifische Logik mit Logik, die in jedem anderen System funktionieren würde.

Dies bedeutet nicht, dass es sich um einen falschen oder schädlichen Ansatz handelt, aber wenn ich persönlich eine Konstante in einer Angular 2-Anwendung möchte , schreibe ich

export const π = 3.14159265;

Genau wie ich es getan hätte, wenn ich AngularJS verwendet hätte.

Je mehr Dinge sich ändern ...

Aluan Haddad
quelle
0

Der beste Weg, um anwendungsweite Konstanten in Angular 2 zu erstellen, ist die Verwendung von environment.ts-Dateien. Der Vorteil der Deklaration solcher Konstanten besteht darin, dass Sie sie je nach Umgebung variieren können, da für jede Umgebung eine andere Umgebungsdatei vorhanden sein kann.

Hassan Arafat
quelle
Dies funktioniert nicht, wenn Sie Ihre Anwendung einmal erstellen und dann in mehreren Umgebungen bereitstellen möchten.
Jens Bodal
-1

Sie können eine Klasse für Ihre globale Variable erstellen und diese Klasse dann wie folgt exportieren:

export class CONSTANT {
    public static message2 = [
        { "NAME_REQUIRED": "Name is required" }
    ]

    public static message = {
        "NAME_REQUIRED": "Name is required",
    }
}

Nach dem Erstellen und Exportieren Ihrer CONSTANTKlasse sollten Sie diese Klasse wie folgt in die Klasse importieren, in der Sie sie verwenden möchten:

import { Component, OnInit                       } from '@angular/core';
import { CONSTANT                                } from '../../constants/dash-constant';


@Component({
  selector   : 'team-component',
  templateUrl: `../app/modules/dashboard/dashComponents/teamComponents/team.component.html`,
})

export class TeamComponent implements OnInit {
  constructor() {
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  }

  ngOnInit() {
    console.log("oninit");
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  }
}

Sie können dies entweder in constructoroder ngOnInit(){}oder in beliebigen vordefinierten Methoden verwenden.

Shubham Verma
quelle