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.
typescript
angular
AndreFeijo
źródło
źródło
AppSettings
klasa powinna być abstrakcyjna, aAPI_ENDPOINT
członek powinienreadonly
.Rozwiązanie konfiguracji zapewnione przez sam zespół kątowy można znaleźć tutaj .
Oto cały odpowiedni kod:
1) app.config.ts
2) app.module.ts
3) your.service.ts
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
źródło
environment.ts
ienvironment.prod.ts
tak, że można mieć różne stałe za środowisko? @IlyaChernomordik zaczął o tym wspominać w ostatnim akapicie swojej odpowiedzi.W Angular2 masz dodaje dostarczyć definicję, która pozwala na ustawienie różnego rodzaju zależnościami:
W porównaniu do Angulara 1
app.service
in Angular1 jest równoważne zuseClass
Angular2.app.factory
in Angular1 jest równoważne zuseFactory
Angular2.app.constant
iapp.value
został uproszczony douseValue
mniej ograniczeń. tzn. nie maconfig
już bloku.app.provider
- Nie ma odpowiednika w Angular 2.Przykłady
Aby skonfigurować z aplikatorem root:
Lub skonfiguruj za pomocą wtryskiwacza twojego komponentu:
provide
jest krótką ręką dla:Dzięki wtryskiwaczowi uzyskanie wartości jest łatwe:
źródło
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
A potem w serwisie:
źródło
const
wnę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.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
environment.qa.ts
environment.dev.ts
Przypadek użycia w aplikacji
Możesz importować środowiska do dowolnego pliku, takiego jak usługi
clientUtilServices.ts
import {environment} from '../../environments/environment';
Przypadek użycia w kompilacji
Otwórz plik kątowy cli
.angular-cli.json
i wewnątrz"apps": [{...}]
dodaj następujący kodJeśli chcesz budować dla produkcji, uruchom
ng build --env=prod
ją, aby odczytać konfigurację z tegoenvironment.prod.ts
samego sposobu, w jaki możesz to zrobić dlaqa
lubdev
## Starsza odpowiedź
Robię coś takiego poniżej u mojego dostawcy:
Następnie mam dostęp do wszystkich danych Constant w dowolnym miejscu
źródło
API_ENDPOINT
wartość może zostać nadpisana w dowolnym momencie. Jeślithis.ConstantService.API_ENDPOINT = 'blah blah'
zostanie zadeklarowany w klasie w dowolnym momencie po zaimportowaniu tak zwanej „stałej” zconstant-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.readonly API_ENDPOINT :String;
ng build --env=prod
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):
Następnie w serwisie wstrzykujemy ten ApiEndpoint do konstruktora usług, a Angular dostarczy go nam na podstawie naszej rejestracji powyżej:
źródło
Oto moje ostatnie doświadczenia z tym scenariuszem:
Ś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
app-config.constants.ts
app.module.ts
my-service.service.ts
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.
źródło
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
app.service.ts
źródło
Wystarczy użyć stałej maszynopisu
Możesz go użyć we wstrzykiwaczu zależności za pomocą
źródło
const
wczorajJeś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
/config
webpack 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
custom-typings.d.ts
Składnik
źródło
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ódło
Jednym podejściem dla Angular4 byłoby zdefiniowanie stałej na poziomie modułu:
Następnie w twoich usługach:
źródło
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.
W folderze aplikacji dodaję folder configs / setting.json
Treść w setting.json
W module aplikacji dodaj APP_INITIALIZER
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.
źródło
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:Porównaj to z dokumentacją dla
module.constant
($provide.constant
), która również wyraźnie określa przypadek użycia (moje wyróżnienie):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
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
jest niejasno arbitralne i nieco odrażające, ponieważ
$provide.constant
jest używane do określenia obiektu, który nawiasem mówiąc, jest również stały. Równie dobrze mógłbyś napisać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
constant
funkcji nie działałoby.Lepszym argumentem i prawdopodobnie jednym bardziej zgodnym z przyczyną istnienia
$provide.constant
funkcji 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ę
tak jak bym zrobił, gdybym używał AngularJS.
Im więcej rzeczy się zmieni ...
źródło
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.
źródło
Możesz utworzyć klasę dla zmiennej globalnej, a następnie wyeksportować tę klasę w następujący sposób:
Po utworzeniu i wyeksportowaniu
CONSTANT
klasy powinieneś zaimportować tę klasę do tej klasy, w której chcesz jej użyć, w następujący sposób:Możesz użyć tego w
constructor
lubngOnInit(){}
, lub w dowolnych predefiniowanych metodach.źródło