Definiowanie stałych globalnych
In Angular 1.x można zdefiniować stałe w następujący sposób:
angular.module('mainApp.config', [])
.constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/')
Jaki byłby odpowiednik w Angular (z maszynopisem)?
Po prostu nie chcę powtarzać podstawowego adresu URL API w kółko we wszystkich moich usługach.
16 answers
Poniższe zmiany działają dla mnie na Angular 2 finalna wersja:
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);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-10 17:24:11
Rozwiązanie dla konfiguracji dostarczonej przez zespół angular 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.moduł.ts
import { APP_CONFIG, AppConfig } from './app.config';
@NgModule({
providers: [
{ provide: APP_CONFIG, useValue: AppConfig }
]
})
3) twój.obsługa.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 wprowadzić konfigurację wszędzie bez używania nazw łańcuchów i przy użyciu interfejsu do kontroli statycznych.
Można oczywiście oddzielić interfejs i stałą dalej, aby móc dostarczyć różne wartości w produkcji i rozwoju np.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-03 16:27:18
W Angular2, masz następującą definicję provide , która pozwala ustawić różne rodzaje zależności:
provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}
W porównaniu do kątowej 1
app.service
w Angular1 jest równoważne useClass
W Angular2.
app.factory
w Angular1 jest równoważne useFactory
W Angular2.
app.constant
i app.value
został uproszczony do {[11] } z mniejszymi ograniczeniami. tzn. nie ma już config
bloku.
app.provider
- nie ma odpowiednika w Kątowa 2.
Przykłady
Do konfiguracji z wtryskiwaczem root:
bootstrap(AppComponent,[provide(API_ENDPOINT, { useValue='http://127.0.0.1:6666/api/' })]);
Lub konfiguracja z wtryskiwaczem 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/'})
]);
Z wtryskiwaczem uzyskanie wartości jest łatwe:
var endpoint = injectorValue.get(API_ENDPOINT);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-12 17:05:04
Aktualizacja dla Angular 4 +
Teraz możemy po prostu użyć pliku environments, który angular zapewnia domyślne, jeśli twój projekt jest generowany przez angular-cli.
Na przykład
W folderze environments Utwórz następujące pliki
environment.prod.ts
environment.qa.ts
environment.dev.ts
I każdy plik może zawierać powiązane zmiany kodu takie as:
-
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 zaimportować środowiska do dowolnego pliku, takiego jak usługiclientUtilServices.ts
import {environment} from '../../environments/environment';
getHostURL(): string {
return environment.apiHost;
}
Przypadek użycia w budowie
Otwórz plik angular CLI .angular-cli.json
i w środku "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 zbudować dla produkcji, Uruchom ng build --env=prod
odczyta konfigurację z environment.prod.ts
, w ten sam sposób można to zrobić dla qa
lub dev
# # starsza odpowiedź
Robiłem coś takiego jak poniżej, w moim providerze:
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'
}
}
Wtedy mam dostęp do wszystkich stałych danych 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)
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-09 07:35:25
W Angular 4, możesz użyć klasy środowiska, aby zachować wszystkie swoje globale.
Masz środowisko.ts i środowisko.prod.ts domyślnie.Na przykład
export const environment = {
production: false,
apiUrl: 'http://localhost:8000/api/'
};
A następnie w serwisie:
import { environment } from '../../environments/environment';
...
environment.apiUrl;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-28 14:17:48
Chociaż podejście z klasą AppSettings ze stałą łańcuchową jako apiendpoint działa, nie jest idealne, ponieważ nie moglibyśmy zamienić tego prawdziwego ApiEndpoint na inne wartości w czasie testów jednostkowych.
Musimy być w stanie wprowadzić te punkty końcowe api do naszych usług (pomyśl o wstrzyknięciu usługi do innej usługi). Nie musimy również tworzyć całej klasy do tego, wszystko co chcemy zrobić, to wstrzyknąć łańcuch do naszych usług będący naszym ApiEndpoint. Na uzupełnij doskonałą odpowiedź przez pixelbits, Oto Pełny kod, jak można to zrobić w Angular 2:
Najpierw musimy powiedzieć Angular, jak dostarczyć instancję naszego punktu ApiEndpoint, gdy poprosimy o nią w naszej aplikacji (pomyśl o tym, jak o zarejestrowaniu zależności):
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide('ApiEndpoint', {useValue: 'http://127.0.0.1:6666/api/'})
]);
A następnie w serwisie wstrzykujemy ten punkt ApiEndpoint do konstruktora serwisu i Angular dostarczy nam go 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...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:54
Oto moje ostatnie doświadczenia z tym scenariuszem:
- @kątowe / cli: 1.0.0
- węzeł: 6.10.2
- @kątowe / rdzeniowe: 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ę OpaqueToken jest teraz przestarzały i musimy użyć InjectionToken , więc są to moje pliki uruchamiane jak czar:
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 żadnych ostrzeżeń na konsoli dziękuję za ostatni komentarz Johna papy w tym numerze:
Https://github.com/angular/angular-cli/issues/2034
Klucz został zaimplementowany w innym pliku interfejsu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-27 22:44:18
Wszystkie rozwiązania wydają się być skomplikowane. Szukam najprostszego rozwiązania dla tej sprawy i chcę tylko 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.obsługa.ts
import * as AppConst from '../app.const';
@Injectable()
export class AppService {
constructor (
) {
console.log('dist path', AppConst.dist );
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-03 16:37:19
Wystarczy użyć stałej maszynopisu
export var API_ENDPOINT = 'http://127.0.0.1:6666/api/';
Możesz go użyć w iniektorze zależności używając
bootstrap(AppComponent, [provide(API_ENDPOINT, {useValue: 'http://127.0.0.1:6666/api/'}), ...]);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-25 07:12:01
Jeśli używasz Webpack, co polecam, możesz ustawić stałe dla różnych środowisk. Jest to szczególnie cenne, gdy masz różne stałe wartości w zależności od środowiska.
Prawdopodobnie będziesz mieć wiele plików webpack w katalogu /config
(np.dev.js, webpack.prod.js itp.). Wtedy będziesz miał custom-typings.d.ts
dodasz je tam. Oto ogólny wzór do naśladowania w każdym pliku i przykładowe użycie w Komponent.
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)
}),
Niestandardowe typy.d. ts
declare var API_URL: string;
declare var JWT_TOKEN_NAME: string;
interface GlobalEnvironment {
API_URL: string;
JWT_TOKEN_NAME: string;
}
Komponent
export class HomeComponent implements OnInit {
api_url:string = API_URL;
authToken: string = "Bearer " + localStorage.getItem(JWT_TOKEN_NAME)});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 21:33:43
Jednym z podejść do 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 służbie:
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);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 12:43:48
Mam inny sposób definiowania stałych globalnych. Ponieważ jeśli zdefiniowaliśmy w pliku ts, jeśli zbudowaliśmy 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
Zawartość w ustawieniu.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 również tego sposobu do ciągłych komunikatów o błędach / ostrzeżeniach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-15 09:19:37
Używanie pliku właściwości generowanego podczas budowania jest proste i łatwe. Jest to podejście, które kątowe CLI używa. 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 aplikacji. Następnie po prostu zaimportuj plik właściwości do użycia.
Https://github.com/angular/angular-cli#build-targets-and-environment-files
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-10 04:00:54
AngularJS module.constant
nie definiuje stałej w sensie standardowym.
Chociaż jest on sam jako mechanizm rejestracji dostawcy, najlepiej jest rozumieć go w kontekście powiązanych module.value
($provide.value
) funkcja. Oficjalna dokumentacja jasno określa przypadek użycia:
Zarejestruj usługę wartości za pomocą $injector, taką jak łańcuch znaków, liczba, tablica, obiekt lub funkcja. Jest to skrót od rejestracji usługi, w której jego właściwość $get jest funkcja factory, która nie pobiera argumentów i zwraca usługę value. Oznacza to również, że nie jest możliwe wstrzyknięcie innych usług do usługi wartości.
Porównaj to z dokumentacją dla module.constant
($provide.constant
) co również jasno określa przypadek użycia (podkreślenie mine):
Zarejestruj stałą usługę za pomocą $injector, taką jak łańcuch znaków, 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 być wprowadzana do funkcji konfiguracyjnej modułu(patrz kąt.Moduł) i nie może być nadpisany przez dekorator AngularJS .
Dlatego funkcja AngularJS constant
nie zapewnia stałej w powszechnie rozumianym znaczeniu tego terminu w polu.
To powiedziawszy ograniczenia nałożone na dostarczony obiekt, wraz z jego wcześniejszą dostępnością za pośrednictwem $injector, wyraźnie sugeruje, że nazwa jest używana przez analogia.
Jeśli chcesz mieć stałą w aplikacji AngularJS, "podaj" ją tak samo jak w każdym programie JavaScript, który jest
export const π = 3.14159265;
W kątowym 2 stosuje się tę samą technikę.
Aplikacje Angular 2 nie mają fazy konfiguracji w tym samym sensie, co Aplikacje AngularJS. Ponadto nie ma mechanizmu dekoratora usługi (AngularJS dekorator ), ale nie jest to szczególnie zaskakujące, biorąc pod uwagę, jak różne są od siebie.
Przykład
angular
.module('mainApp.config', [])
.constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/');
Jest niejasno arbitralne i nieco odpychające, ponieważ $provide.constant
jest używany do określenia obiektu, który jest nawiasem mówiąc również stałą. Równie dobrze mogłeś napisać
export const apiEndpoint = 'http://127.0.0.1:6666/api/';
Dla wszystkich, które mogą się zmienić.
Teraz argument za testowalnością, wyśmiewając stałą, jest pomniejszony, ponieważ dosłownie się nie zmienia.
Nie wyśmiewa się π.
Oczywiście twoje podanie specyficzną semantyką może być zmiana punktu końcowego API lub nieprzezroczysty mechanizm przełączania awaryjnego, więc w pewnych okolicznościach rozsądne byłoby, aby punkt końcowy API uległ zmianie.
Ale w takim przypadku podanie go jako ciąg znaków literalnej reprezentacji pojedynczego adresu URL do funkcji constant
nie zadziałałoby.
Lepszym argumentem i prawdopodobnie jeszcze jednym z powodów istnienia funkcji AngularJS $provide.constant
jest to, że gdy AngularJS został wprowadzony, JavaScript nie miał standardowej koncepcji modułu. W takim przypadku globale byłyby używane do dzielenia się wartościami, zmiennymi lub niezmiennymi, a używanie globali jest problematyczne.
To powiedziawszy, dostarczenie czegoś takiego poprzez ramy zwiększa powiązanie z tymi ramami. Łączy również logikę kątową z logiką, która działa w każdym innym systemie.
To nie znaczy, że jest to złe lub szkodliwe podejście, ale osobiście, jeśli chcę stała W Angular 2 application, I will write
export const π = 3.14159265;
Tak jak ja używałbym AngularJS.
Im więcej rzeczy się zmienia...Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-27 00:50:24
Najlepszym sposobem tworzenia stałych szerokich aplikacji w Angular 2 jest użycie środowiska.pliki ts. Zaletą deklarowania takich stałych jest to, że można je zmieniać w zależności od środowiska, ponieważ dla każdego środowiska może istnieć inny plik środowiskowy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-18 16:08:30
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 klasy CONSTANT
, powinieneś zaimportować tę klasę do tej klasy, której chcesz 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 constructor
lub ngOnInit(){}
, lub w dowolnych predefiniowanych metodach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-22 10:11:10