2016-03-23 66 views
9

有一個excellent article如何異步引導angular1應用程序。這使我們能夠在引導之前從服務器獲取json。如何異步引導Angular 2應用程序

主要代碼是在這裏:

(function() { 
    var myApplication = angular.module("myApplication", []); 

    fetchData().then(bootstrapApplication); 

    function fetchData() { 
     var initInjector = angular.injector(["ng"]); 
     var $http = initInjector.get("$http"); 

     return $http.get("/path/to/data.json").then(function(response) { 
      myApplication.constant("config", response.data); 
     }, function(errorResponse) { 
      // Handle error case 
     }); 
    } 

    function bootstrapApplication() { 
     angular.element(document).ready(function() { 
      angular.bootstrap(document, ["myApplication"]); 
     }); 
    } 
}()); 

如何實現與角2一樣的嗎?

+0

相同的方式。 。 。 –

+0

所以我應該看看如何使用angular2注入器手動獲取http客戶端? –

+2

類似'new Injector([HTTP_PROVIDERS])。get(Http)' –

回答

14

實際上,您需要在應用程序本身之外明確創建一個注入器以獲取Http的實例來執行請求。然後,在加載應用程序時,可以將加載的配置添加到提供程序中。

這裏有一個例子:

import {bootstrap} from 'angular2/platform/browser'; 
import {provide, Injector} from 'angular2/core'; 
import {HTTP_PROVIDERS, Http} from 'angular2/http'; 
import {AppComponent} from './app.component'; 
import 'rxjs/Rx'; 

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

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

然後你就可以擁有由依賴注入訪問配置:

import {Component, Inject} from 'angular2/core'; 

@Component({ 
    selector: 'app', 
    template: ` 
    <div> 
     Test 
    </div> 
    ` 
}) 
export class AppComponent { 
    constructor(@Inject('config') private config) { 
    console.log(config); 
    } 
} 

看到這個plunkr:https://plnkr.co/edit/kUG4Ee9dHx6TiJSa2WXK?p=preview

+1

首先,非常感謝這個解決方案。其次,在這種情況下,承諾會更好,因爲你可能只會期待一個結果,並且你希望在任何一種情況下都能得到迴應(成功或失敗)?即'http.get('data.json')。toPromise()'或者它真的很重要嗎? – dspies

+1

@dspies不客氣!我理解你對promise的評論,但在http的情況下,只有一個事件被解僱,並且在......之後完成。因此,不需要轉換爲promise ;-) –

3

我試圖解決類似的問題,我不僅需要異步引導應用程序,還需要在我的應用程序中使用異步初始化服務。 這是解決方案,也許這將是有用的人:

let injector = ReflectiveInjector.resolveAndCreate([Service1, 
{ 
    provide: Service2, 
    useFactory: (s1: Service1) => new Service1(s2), 
    deps: [Service1] 
}]); 

let s1: Service1 = injector.get(Service1); 
let s2: Service2 = injector.get(Service2); 

s2.initialize().then(() => { 
bootstrap(Application, [ 
    ...dependencies, 
    { 
     provide: Service2, 
     useValue: s2  // this ensures that the existing instance is used 
    } 
    // Service2 - this would create a new instance and the init would be lost 
    ]); 
}); 
0

的蒂埃裏TEMPLIER方法也適用與jQuery。 這裏是我的角度2.3.1(文件main.ts)的解決方案:

import './polyfills.ts'; 

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 
import { enableProdMode } from '@angular/core'; 
import { environment } from './environments/environment'; 
import { AppModule } from './app/app.module'; 
declare var $: any; 

if (environment.production) { 
    enableProdMode(); 
} 

$.ajax({ 
    'url': './assets/config.json', 
    'type': 'GET', 
    'success': function(data) { 
     platformBrowserDynamic(
     [ 
      { 
      provide: 'appConfig', 
      useValue: data 
      } 
     ] 
    ).bootstrapModule(AppModule); 
    } 
}); 
相關問題