2016-03-31 11 views
9

Poniższy scenariusz: Buduję aplikację AngularJS 2, która pobiera interfejs REST API (który można zbudować za pomocą Elixir, RoR lub cokolwiek innego). W trakcie rozwoju chcę, aby AngularJS zużywał inne API niż w produkcji (może z danymi testowymi, może dlatego, że buduję API w tym samym czasie i działa na moim komputerze).AngularJS 2: Obsługa konfiguracji aplikacji dla różnych środowisk

Dodatkowo inni członkowie mojego zespołu mogą chcieć użyć innego lokalnego adresu API. Oznacza to, że nie powinno to wchodzić w system kontroli wersji.

Na przykład api_base_url może być http://localhost:4000 dla mnie, http://testapi.local dla mojego kolegi i http://api.example.com do produkcji.

Wartość api_base_url powinna być dostępna w wielu komponentach.

Jakie jest dobre podejście do radzenia sobie z tym?

Odpowiedz

4

Można zdefiniować dedykowanego dostawcę, pod warunkiem że te wskazówki. Coś w tym stylu:

bootstrap(AppComponent, [ 
    (...) 
    provide('configuration', { 
    useValue: { 
     apiBaseUrl: 'http://localhost:4000' 
    } 
    } 
]); 

Podczas pakowania kodu do produkcji można zastąpić plik zawierający ten kod plikiem z konfiguracją do produkcji.

Aby uwzględnić tę konfigurację, można rozszerzyć klasę RequestOptions poprzedzający wszystkie żądania z apiBaseUrl prefix:

import { 
    BaseRequestOptions, RequestOptions, RequestOptionsArgs 
} from 'angular2/http'; 

export class AppRequestOptions extends BaseRequestOptions { 
    constructor(private @Inject('configuration') configuration:any) { 
    } 

    merge(options?:RequestOptionsArgs):RequestOptions { 
    options.url = this.configuration.apiBaseUrl + options.url; 
    return super.merge(options); 
    } 
} 

nie zapomnij, aby skonfigurować opcje żądanie podczas uruchamiania się aplikacji:

bootstrap(AppComponent, [ 
    (...) 
    provide('configuration', { 
    useValue: { 
     apiBaseUrl: 'http://localhost:4000' 
    } 
    } 
    provide(RequestOptions, { useClass: AppRequestOptions }) 
]); 

To przetwarzanie może być zawarte w dedykowanym pliku JS, który zostanie zastąpiony w kompilacji (na przykład z gulp i gulp-html-replace).

Zobacz na to pytanie:

dla ostatniego kroku, można również ładować asynchronicznie aplikacji na podstawie pliku konfiguracyjnego:

var injector = Injector.resolveAndCreate([HTTP_PROVIDERS]); 
var http = injector.get(Http); 

http.get('config.json').map(res => res.json()) 
    .subscribe(data => { 
    bootstrap(AppComponent, [ 
     HTTP_PROVIDERS 
     provide('config', { useValue: data }) 
    ]); 
    }); 

zobaczyć to pytanie więcej szczegółów:

+0

Ale to by znaczyło, że muszę skopiować i wkleić we właściwej konfiguracji w zależności od środowiska. Myślę, że byłoby bardziej elegancko, gdybym miał plik konfiguracyjny dla każdego środowiska, który jest poza kontrolą wersji i mógłby być indywidualny dla każdego członka zespołu. Kopiowanie i wklejanie przed kompilacją również nie wydaje się świetnym pomysłem, jeśli chcesz mieć automatyczny przepływ i CI. –

+1

Nie byłoby ręcznego kopiowania/wklejania, ale zintegrowane z twoją kompilacją (na przykład z gulp i gulp-html-replace). Zobacz to pytanie: http: // stackoverflow.com/questions/36285064/how-do-i-faktycznie-deploy-an-angle-2-typescript-systemjs-app/36315060 –

+1

Innym podejściem byłoby boostrap aplikacji po załadowaniu pliku konfiguracyjnego. Odpowiednio zaktualizowałem swoją odpowiedź ... –

Powiązane problemy