Zdefiniuj stałe globalne

258

W Angular 1.x możesz zdefiniować takie stałe:

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

Jaki byłby odpowiednik w Angular (z TypeScript)?

Po prostu nie chcę powtarzać podstawowego adresu URL interfejsu API we wszystkich moich usługach.

AndreFeijo
źródło

Odpowiedzi:

265

Poniższe zmiany działają dla mnie w ostatecznej wersji Angular 2:

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

A potem w serwisie:

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
źródło
Myślę, że twoja AppSettingsklasa powinna być abstrakcyjna, a API_ENDPOINTczłonek powinien readonly.
Philippe Gioseffi
164

Rozwiązanie konfiguracji zapewnione przez sam zespół kątowy można znaleźć tutaj .

Oto cały odpowiedni kod:

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

Teraz możesz wstrzykiwać konfigurację wszędzie bez użycia nazw ciągów i przy użyciu interfejsu do kontroli statycznych.

Możesz oczywiście oddzielić interfejs od stałej, aby móc dostarczać różne wartości w produkcji i rozwoju, np

Ilya Chernomordik
źródło
3
Działa tylko wtedy, gdy nie podam typu w konstruktorze usługi. Działa to wtedy, gdy wykonuję konstruktor (prywatna konfiguracja @Inject (APP_CONFIG)) {} Jest tu wzmianka o tym: blog.thoughtram.io/angular/2016/05/23/... ale nie dlaczego.
Mukus,
Podejrzewam, że przegapiłeś jakieś słowo kluczowe importu lub eksportu, lub coś w tym stylu, ponieważ używam go z interfejsem i, jak mówisz, bardzo ważne jest, aby było wyraźnie wpisane statycznie. Być może musisz podać tutaj dokładny wyjątek.
Ilya Chernomordik
46
Żadne z tych rozwiązań, nawet podejście kanciaste zalecane nie wygląda elegancko. Dlaczego próba tworzenia stałych jest uciążliwym procesem w Angular 2? Nie widzisz, jak bezproblemowa zrobiła to Angular1? Dlaczego cały bałagan?
KhoPhi,
31
Dla każdego, kto trafi w tę odpowiedź, OpaqueToken w Angular v4 jest „przestarzały” dla InjectionToken - blog.thoughtram.io/angular/2016/05/23/…
mtpultz
3
Wydaje się rozsądne, aby umieścić kod z Kroku 1 do environment.tsi environment.prod.tstak, że można mieć różne stałe za środowisko? @IlyaChernomordik zaczął o tym wspominać w ostatnim akapicie swojej odpowiedzi.
Robert Bernstein,
64

W Angular2 masz dodaje dostarczyć definicję, która pozwala na ustawienie różnego rodzaju zależnościami:

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

W porównaniu do Angulara 1

app.servicein Angular1 jest równoważne z useClassAngular2.

app.factoryin Angular1 jest równoważne z useFactoryAngular2.

app.constanti app.valuezostał uproszczony do useValuemniej ograniczeń. tzn. nie ma configjuż bloku.

app.provider - Nie ma odpowiednika w Angular 2.

Przykłady

Aby skonfigurować z aplikatorem root:

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

Lub skonfiguruj za pomocą wtryskiwacza twojego komponentu:

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

provide jest krótką ręką dla:

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

Dzięki wtryskiwaczowi uzyskanie wartości jest łatwe:

var endpoint = injectorValue.get(API_ENDPOINT);
piksele
źródło
2
Naprawdę chciałbym mieć moje ustawienia w pliku zewnętrznym, np .: settings.ts Jak wyglądałby ten plik?
AndreFeijo
Czy zastanawiałeś się nad javascript po stronie serwera, takim jak NodeJS?
pixelbits
5
Przepraszam, nie rozumiem, jak mam to wstrzyknąć do mojej usługi? Czy w przypadku korzystania z zewnętrznego pliku muszę go wyeksportować?
AndreFeijo
Sprawiłbym, że będzie to częścią twojego procesu konfiguracji kompilacji. tzn. na podstawie środowiska, skompiluj / spakuj różne pliki razem, a następnie wdróż. Wszystko to możesz zrobić za pomocą NodeJS z odpowiednimi modułami.
pixelbits
1
NodeJS nie jest niestety opcją.
AndreFeijo
59

W Angular 4 możesz użyć klasy środowiska, aby zachować wszystkie globale.

Domyślnie masz environment.ts i environment.prod.ts.

Na przykład

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

A potem w serwisie:

import { environment } from '../../environments/environment';
...
environment.apiUrl;
Nacho
źródło
Jeśli próbujesz uzyskać dostęp do constwnętrza usługi, być może trzeba będzie „zapewnienie” go w swojej aplikacji dostawców tablicy modułu: { provide: 'ConstName', useValue: ConstName }. Dostałem błąd wykonania bez tego.
daleyjem
@daleyjem to dlatego, że próbowałeś to wstrzyknąć. W tym podejściu nie stosuje się wtryskiwacza
Aluan Haddad,
Tworzenie stałej takiej jak ta jest najprostsze. Sądzę, że kontrargument utraty utraty DI, a tym samym utraty testowalności / mockValue, jest czasem przesadzony. W typowej aplikacji korzystamy z wielu komponentów innych niż DI, takich jak (RxJS), bez niepotrzebnego testowania.
Amitesh
54

Zaktualizowano dla Angular 4+

Teraz możemy po prostu użyć pliku środowisk, który domyślnie dostarcza kąt, jeśli twój projekt jest generowany przez angular-cli.

na przykład

W folderze środowiska utwórz następujące pliki

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

a każdy plik może zawierać powiązane zmiany kodu, takie jak:

  • 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' ],
    };

Przypadek użycia w aplikacji

Możesz importować środowiska do dowolnego pliku, takiego jak usługi clientUtilServices.ts

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

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

Przypadek użycia w kompilacji

Otwórz plik kątowy cli .angular-cli.jsoni wewnątrz "apps": [{...}]dodaj następujący kod

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

Jeśli chcesz budować dla produkcji, uruchom ng build --env=prodją, aby odczytać konfigurację z tego environment.prod.tssamego sposobu, w jaki możesz to zrobić dla qalubdev

## Starsza odpowiedź

Robię coś takiego poniżej u mojego dostawcy:

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'
  }
}

Następnie mam dostęp do wszystkich danych Constant w dowolnym miejscu

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 ....
źródło
6
To nie działa jak stała. Wartość stałej jest zawsze taka sama. W twoim przypadku twoja API_ENDPOINTwartość może zostać nadpisana w dowolnym momencie. Jeśli this.ConstantService.API_ENDPOINT = 'blah blah'zostanie zadeklarowany w klasie w dowolnym momencie po zaimportowaniu tak zwanej „stałej” z constant-service, nowa wartość API_ENDPOINT będzie 'blah blah'. Twoje rozwiązanie pokazuje tylko, jak uzyskać dostęp do zmiennej przy użyciu usługi, a nie przy użyciu stałej.
Devner,
1
@Devner uczyń je tylko do odczytureadonly API_ENDPOINT :String;
Flavien Volken
@Anjum Jak kątowy wybiera pliki env. Czy powinienem podać nazwę env podczas uruchamiania aplikacji?
konkurs pojęć
@notionquest Tak, możesz to przekazać, jakng build --env=prod
Anjum ....
31

Chociaż podejście polegające na posiadaniu klasy AppSettings ze stałą ciągu jako ApiEndpoint działa, nie jest idealne, ponieważ nie bylibyśmy w stanie zamienić tego prawdziwego ApiEndpoint na inne wartości podczas testowania jednostkowego.

Musimy być w stanie wstrzyknąć punkty końcowe interfejsu API do naszych usług (pomyśl o wstrzyknięciu usługi do innej usługi). Nie musimy też tworzyć do tego całej klasy, wszystko, co chcemy zrobić, to wstrzyknąć ciąg znaków do naszych usług będących naszym ApiEndpoint. Aby uzupełnić doskonałą odpowiedź bitbicami , oto kompletny kod, jak można to zrobić w Angular 2:

Najpierw musimy powiedzieć Angularowi, jak udostępnić instancję naszego ApiEndpoint, gdy poprosimy o to w naszej aplikacji (pomyśl o tym jako o rejestrowaniu zależności):

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


Następnie w serwisie wstrzykujemy ten ApiEndpoint do konstruktora usług, a Angular dostarczy go nam na podstawie naszej rejestracji powyżej:

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
źródło
1
Istnieje teraz „oficjalny” sposób robienia rekomendacji przez zespół Angular w ich samouczku. Dodałem odpowiedź poniżej: ( stackoverflow.com/a/40287063/1671558 )
Ilya Chernomordik
1
ten kod nie jest już dokładny, jego implementacja spowoduje, że ApiEndpoint nie zostanie znaleziony w AppComponent.
WilliamX
Ok, więc nie jestem sam. Czy wiesz, która wersja się zepsuła? Czy istnieje alternatywny sposób, który nie wymaga zdefiniowania wartości na obiekcie globalnym, a następnie ich podania?
Jens Bodal
29

Oto moje ostatnie doświadczenia z tym scenariuszem:

  • @ angular / cli: 1.0.0
  • węzeł: 6.10.2
  • @ kątowy / rdzeń: 4.0.0

Śledziłem oficjalne i zaktualizowane dokumenty tutaj:

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

Wydaje się, że OpaqueToken jest teraz przestarzały i musimy użyć InjectionToken , więc moje pliki działają jak urok:

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@

  }

Wynik jest czysty i nie ma ostrzeżeń na konsoli dzięki niedawnemu komentarzowi Johna Papy w tym numerze:

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

Klucz został zaimplementowany w innym pliku interfejsu.

JavierFuentes
źródło
patrz także stackoverflow.com/a/43193574/3092596 - który jest w zasadzie taki sam, ale tworzy moduły do ​​wstrzykiwania zamiast dostawców
goredwards
19

Wszystkie rozwiązania wydają się skomplikowane. Szukam najprostszego rozwiązania dla tego przypadku i chcę po prostu użyć stałych. Stałe są proste. Czy jest coś, co przemawia przeciwko poniższemu rozwiązaniu?

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
źródło
2
Cóż, używasz zmiennych poza zakresem usługi, więc równie dobrze możesz wtedy użyć globalnych okien. To, co próbujemy zrobić, to wprowadzić stałe do systemu wstrzykiwania zależności Angular4, abyśmy mogli utrzymać zakres, w czystości, na żądanie lub na próbę.
Joel Hernandez,
11

Wystarczy użyć stałej maszynopisu

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

Możesz go użyć we wstrzykiwaczu zależności za pomocą

bootstrap(AppComponent, [provide(API_ENDPOINT, {useValue: 'http://127.0.0.1:6666/api/'}), ...]);
SnareChops
źródło
1
Po co to wstrzykiwać? Myślę, że nie ma takiej potrzeby ... możesz z niego korzystać zaraz po zaimportowaniu. @SnareChops
Sasxa
@Sasxa Zgadzam się, choć może być dobry do testów jednostkowych i tym podobnych. Po prostu próbuję udzielić pełnej odpowiedzi.
SnareChops
1
@Andreas Możesz użyć constwczoraj
SnareChops
Podaj stackblitz tego działania. Widziałem tak wiele przykładów świadczenia usługi w metodzie bootstrap, ale jeszcze nie znalazłem takiej z wystarczająco działającym przykładem. Być może coś się zmieniło w nowszej wersji kątowej.
Jens Bodal
4

Jeśli korzystasz z pakietu WebPack , który polecam, możesz ustawić stałe dla różnych środowisk. Jest to szczególnie cenne, gdy masz różne stałe wartości dla poszczególnych środowisk.

Prawdopodobnie będziesz mieć wiele plików /configwebpack w swoim katalogu (np. Webpack.dev.js, webpack.prod.js itp.). Następnie będziesz mieć custom-typings.d.ts, że dodasz je tam. Oto ogólny wzorzec postępowania w każdym pliku i przykładowe użycie w komponencie.

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;
}

Składnik

export class HomeComponent implements OnInit {
  api_url:string = API_URL;
  authToken: string = "Bearer " + localStorage.getItem(JWT_TOKEN_NAME)});
}
okazyjnie
źródło
3

Korzystanie z pliku właściwości generowanego podczas kompilacji jest proste i łatwe. Takie podejście stosuje Angular CLI. Zdefiniuj plik właściwości dla każdego środowiska i użyj polecenia podczas kompilacji, aby określić, który plik zostanie skopiowany do Twojej aplikacji. Następnie wystarczy zaimportować plik właściwości do użycia.

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

R.Creager
źródło
3

Jednym podejściem dla Angular4 byłoby zdefiniowanie stałej na poziomie modułu:

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

Następnie w twoich usługach:

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
źródło
3

Mam inny sposób na zdefiniowanie stałych globalnych. Ponieważ jeśli zdefiniowaliśmy w pliku ts, jeśli budujemy w trybie produkcyjnym, nie jest łatwo znaleźć stałe do zmiany wartości.

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

W folderze aplikacji dodaję folder configs / setting.json

Treść w setting.json

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

W module aplikacji dodaj APP_INITIALIZER

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

w ten sposób mogę łatwiej zmienić wartość w pliku json. Używam tego również do ciągłego wyświetlania komunikatów o błędach / ostrzeżeniach.

Hien Nguyen
źródło
0

AngularJS's module.constant nie definiuje stałej w sensie standardowym.

Chociaż działa jako mechanizm rejestracji dostawcy, najlepiej jest go rozumieć w kontekście funkcji powiązanej module.value( $provide.value). Oficjalna dokumentacja wyraźnie określa przypadek użycia:

Zarejestruj usługę wartości za pomocą $ injector, taką jak ciąg, liczba, tablica, obiekt lub funkcja. Jest to skrót od rejestracji usługi, w której właściwość $ get jego dostawcy jest funkcją fabryczną, która nie przyjmuje argumentów i zwraca usługę wartości. Oznacza to również, że nie można wstrzykiwać innych usług do usługi o wartości.

Porównaj to z dokumentacją dla module.constant( $provide.constant), która również wyraźnie określa przypadek użycia (moje wyróżnienie):

Zarejestruj stałą usługę za pomocą $ injector, taką jak ciąg, liczba, tablica, obiekt lub funkcja. Podobnie jak wartość, nie jest możliwe wstrzyknięcie innych usług do stałej. Ale w przeciwieństwie do wartości, stała może zostać wstrzyknięta do funkcji konfiguracji modułu (patrz angular.Module) i nie może zostać zastąpiona przez dekorator AngularJS .

Dlatego AngularJS constant funkcja nie zapewnia stałej w powszechnie rozumianym znaczeniu tego terminu w tej dziedzinie.

To powiedziawszy, ograniczenia nałożone na udostępniony obiekt, wraz z jego wcześniejszą dostępnością przez $ injector, wyraźnie sugerują, że nazwa jest używana przez analogię.

Jeśli chcesz rzeczywistą stałą w aplikacji AngularJS, „dostarczysz” ją w taki sam sposób, jak w każdym programie JavaScript, który jest

export const π = 3.14159265;

W Angular 2 obowiązuje ta sama technika.

Aplikacje Angular 2 nie mają fazy konfiguracji w tym samym sensie, co aplikacje AngularJS. Ponadto nie ma mechanizmu dekoratora usług ( AngularJS Decorator ), ale nie jest to szczególnie zaskakujące, biorąc pod uwagę, jak różnią się one od siebie.

Przykład

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

jest niejasno arbitralne i nieco odrażające, ponieważ $provide.constantjest używane do określenia obiektu, który nawiasem mówiąc, jest również stały. Równie dobrze mógłbyś napisać

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

wszyscy mogą się zmienić.

Teraz argument za testowalnością, kpiącą ze stałej, jest mniejszy, ponieważ dosłownie się nie zmienia.

Nie kpi się z π.

Oczywiście semantyka specyficzna dla aplikacji może polegać na tym, że punkt końcowy może ulec zmianie lub interfejs API może mieć nieprzejrzysty mechanizm przełączania awaryjnego, więc rozsądne byłoby, aby punkt końcowy interfejsu API zmienił się w pewnych okolicznościach.

Ale w takim przypadku podanie jej jako dosłownego ciągu pojedynczego adresu URL constantfunkcji nie działałoby.

Lepszym argumentem i prawdopodobnie jednym bardziej zgodnym z przyczyną istnienia $provide.constantfunkcji AngularJS jest to, że kiedy wprowadzono AngularJS, JavaScript nie miał standardu koncepcji modułu. W takim przypadku globale byłyby używane do dzielenia wartości, zmiennych lub niezmiennych, a używanie globałów jest problematyczne.

To powiedziawszy, dostarczenie czegoś takiego poprzez framework zwiększa sprzężenie z tym frameworkem. Łączy również logikę kątową z logiką, która działałaby w każdym innym systemie.

Nie oznacza to, że jest to złe lub szkodliwe podejście, ale osobiście, jeśli chcę stałą w aplikacji Angular 2, napiszę

export const π = 3.14159265;

tak jak bym zrobił, gdybym używał AngularJS.

Im więcej rzeczy się zmieni ...

Aluan Haddad
źródło
0

Najlepszym sposobem na utworzenie stałych aplikacji w Angular 2 jest użycie plików environment.ts. Zaletą deklarowania takich stałych jest to, że można je różnicować w zależności od środowiska, ponieważ dla każdego środowiska może istnieć inny plik środowiska.

Hassan Arafat
źródło
Nie działa to, jeśli zamierzasz kiedyś zbudować aplikację, a następnie wdrożyć ją w wielu środowiskach.
Jens Bodal
-1

Możesz utworzyć klasę dla zmiennej globalnej, a następnie wyeksportować tę klasę w następujący sposób:

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

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

Po utworzeniu i wyeksportowaniu CONSTANTklasy powinieneś zaimportować tę klasę do tej klasy, w której chcesz jej użyć, w następujący sposób:

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

Możesz użyć tego w constructorlub ngOnInit(){}, lub w dowolnych predefiniowanych metodach.

Shubham Verma
źródło