update2
Plunker exemple
mise à jour AoT
Travailler avec AoT la fermeture d'usine doit être déplacé
function loadContext(context: ContextService) {
return () => context.load();
}
@NgModule({
...
providers: [ ..., ContextService, { provide: APP_INITIALIZER, useFactory: loadContext, deps: [ContextService], multi: true } ],
Voir aussi https://github.com/angular/angular/issues/11262
mise à jour d'un RC.6 et 2.0.0 dernier exemple
function configServiceFactory (config: ConfigService) {
return () => config.load();
}
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule,
routes,
FormsModule,
HttpModule],
providers: [AuthService,
Title,
appRoutingProviders,
ConfigService,
{ provide: APP_INITIALIZER,
useFactory: configServiceFactory
deps: [ConfigService],
multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Si il n'est pas nécessaire d'attendre l'initialisation, le constructeur de la classe de AppModule {} peut également être utilisé:
class AppModule {
constructor(/*inject required dependencies */) {...}
}
conseil (dépendance cyclique)
Par exemple, l'injection du routeur peut provoquer des dépendances cycliques.
Pour contourner, d'injecter de l' Injector
et obtenir de la dépendance par
this.myDep = injector.get(MyDependency);
au lieu d'injecter MyDependency
directement avec:
@Injectable()
export class ConfigService {
private router:Router;
constructor(/*private router:Router*/ injector:Injector) {
setTimeout(() => this.router = injector.get(Router));
}
}
mise à jour
Cela devrait fonctionner de la même dans le RC.5 mais au lieu d'ajouter le fournisseur d' providers: [...]
de la racine du module à la place de bootstrap(...)
(pas testé moi-même encore).
mise à jour
Une approche intéressante pour le faire entièrement à l'intérieur Angulaire est expliqué ici https://github.com/angular/angular/issues/9047#issuecomment-224075188
Vous pouvez utiliser APP_INITIALIZER
qui va exécuter une fonction lorsque la
app est initialisé de retard et de ce qu'il prévoit que si la fonction renvoie
une promesse. Cela signifie que l'application peut être initialisation sans tout à fait aussi
beaucoup de latence et vous pouvez également utiliser les services existants et le cadre
les fonctionnalités.
Par exemple, supposons que vous avez un multi-tenanted solution où l'
info sur le site s'appuie sur le nom de domaine, il est servi à partir de. Cela peut
[nom].letterpress.com ou un domaine personnalisé qui est mentionné sur le
nom d'hôte complet. On peut cacher le fait que c'est derrière une promesse faite par la
à l'aide de APP_INITIALIZER
.
Dans le bootstrap:
{provide: APP_INITIALIZER, useFactory: (sites:SitesService) => () => sites.load(), deps:[SitesService, HTTP_PROVIDERS], multi: true}),
sites.service.ts:
@Injectable()
export class SitesService {
public current:Site;
constructor(private http:Http, private config:Config) { }
load():Promise<Site> {
var url:string;
var pos = location.hostname.lastIndexOf(this.config.rootDomain);
var url = (pos === -1)
? this.config.apiEndpoint + '/sites?host=' + location.hostname
: this.config.apiEndpoint + '/sites/' + location.hostname.substr(0, pos);
var promise = this.http.get(url).map(res => res.json()).toPromise();
promise.then(site => this.current = site);
return promise;
}
REMARQUE: config
est juste une configuration personnalisé de classe. rootDomain
serait
'.letterpress.com'
pour cet exemple et permettre des choses comme
aptaincodeman.letterpress.com
.
Tous les composants et d'autres services peuvent maintenant avoir Site
injecté dans
et de les utiliser l' .current
de la propriété qui sera un béton
peuplé d'objets sans avoir à attendre sur toute promesse au sein de l'application.
Cette approche semblait couper le démarrage de la latence qui est par ailleurs
tout à fait perceptible si vous avez été en attente pour le grand Angulaire du faisceau à
charger, puis une autre requête http avant le bootstrap même a commencé.
d'origine
Vous pouvez passer à l'aide de Angulars de l'injection de dépendances:
var headers = ... // get the headers from the server
bootstrap(AppComponent, [{provide: 'headers', useValue: headers})]);
class SomeComponentOrService {
constructor(@Inject('headers') private headers) {}
}
ou de fournir préparé BaseRequestOptions
directement comme
class MyRequestOptions extends BaseRequestOptions {
constructor (private headers) {
super();
}
}
var values = ... // get the headers from the server
var headers = new MyRequestOptions(values);
bootstrap(AppComponent, [{provide: BaseRequestOptions, useValue: headers})]);