Porównaj ceny domen i usług IT, sprzedawców z całego świata

Angular2 ładuje konfigurację z backendu przy starcie


W mojej aplikacji Angular2 próbuję załadować konfiguracje z zaplecza do ładowania początkowego przy użyciu protokołu HTTP, aby użyć pobranych danych do tworzenia usług kątowych.
Za każdym razem, gdy próbuję odczytać odpowiedź HTTP zapisaną w mojej konfiguracji, zawsze otrzymuję

TypeError: nie można odczytać właściwości „url” undefined

błędy.
Wygląda na to, że żądanie HTTP kończy się dopiero po zakończeniu całej metody ładowania początkowego, podczas gdy mój kod próbuje pobrać obserwowalną odpowiedź przed jej pobraniem.
Jak mogę to naprawić, aby pobrać konfigurację z serwera i użyć jej do tworzenia usług kątowych podczas uruchamiania? (Chcę tworzyć usługi wewnątrz dostawców z wyodrębnionymi danymi)
Prosimy o komentarz, jeśli istnieje lepszy sposób na pobranie konfiguracji z serwera przy starcie.
Mój

main.ts

na to wygląda:
<pre class="lang-js prettyprint-override">
bootstrap(AppComponent, 
[APP_ROUTER_PROVIDERS, HTTP_PROVIDERS, ConfigurationService, Config])
.catch(err => console.error(err));


configuration.service.ts

<pre class="lang-js prettyprint-override">
@Injectable()
export class ConfigurationService { constructor(private http: Http) {
} load() {
return this.http.get('config/getConfig').map(response => response.json());
}}


config.ts

<pre class="lang-js prettyprint-override">
@Injectable()
export class Config { public config; constructor(public configurationService: ConfigurationService) {
configurationService.load().subscribe( config => this.config = config,
error => console.error('Error: ' + error)
);
} get(key: any) {
return this.config[key];
}
}


app.component.ts

<pre class="lang-js prettyprint-override">
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
styleUrls: ['app/app.component.css'],
directives: [ROUTER_DIRECTIVES],
providers: [MyService]
})
export class AppComponent { constructor(public myService: MyService) {
}}


my.service.ts

<pre class="lang-js prettyprint-override">
@Injectable()
export class MyService{ private url; constructor(public config: Config) {
this.url = config.get('url');
}
}

Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz skorzystać z usługi
APP_INITIALIZER
, aby ponownie załadować konfigurację przed uruchomieniem aplikacji:
<pre class="lang-js prettyprint-override">
bootstrap(AppComponent, [
{
provide: APP_INITIALIZER,
useFactory: (config:Config) => {
return config.load();
},
dependency: [ Config ]
}
]);

Aby to zrobić, musisz nieco dostosować klasę
ConfigService
:
<pre class="lang-js prettyprint-override">
@Injectable()
export class ConfigService {
constructor(private http:Http) {} load() {// <------
return new Promise((resolve) => {
this.http.get(...).map(res=>res.json())
.subscribe(config => {
this.config = config;
resolve();
});
}
}

Wtedy będziesz mógł uzyskać bezpośredni dostęp do właściwości obiektu config w swojej aplikacji.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Podczas korzystania z kompilacji AoT występuje błąd, ponieważ fabryka jest funkcją anonimową. Musisz wyeksportować funkcję dla fabryki
<pre class="lang-js prettyprint-override">
export function ConfigLoader(configService: ConfigService) {
return () => configService.load();
}

a konfiguracja aplikacji wygląda następująco:
<pre class="lang-js prettyprint-override">
@NgModule({
declarations: [
AppComponent
],
imports: [
HttpModule,
BrowserModule
],
providers: [
ConfigService,
{
provide: APP_INITIALIZER,
useFactory: ConfigLoader,
deps: [ConfigService]
}],
bootstrap: [ AppComponent ]
})
export class AppModule {
}

połączyć

https://github.com/angular/angular/issues/10789
https://github.com/angular/angular/issues/10789
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To najlepszy sposób na napisanie funkcji ładowania
<pre class="lang-js prettyprint-override">
public load() {
let promise =this.http.get(url).map(res => res.json()).toPromise();
promise.then(config => this.validation = config);
return promise;
};

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się