问题
Is it possible to manually resolve a component by only knowing it's name?
I have a string variable which will contain the name of a component, lets say "UserService"
I need to be able to resolve this type, I've looked at Injctor
, I can see from the documenation there is a resolve()
and resolveAndCreate()
(https://angular.io/docs/ts/latest/api/core/Injector-class.html)
but I don't have the Type.
Thanks
Steve
EDIT: tried the following:
System.import("path/to/service").then(p=>{
var injector = Injector.resolveAndCreate([p[this.serviceName]]);//works
var serviceInstance = injector.get(p[this.serviceName]); //Fails with "No provider for Http! (UserService -> Http)".
});
I have Http
available, it's been provided during bootstrap and this works fine for other parts of the application.
bootstrap(AppComponent, [
ROUTER_PROVIDERS, Http, HTTP_PROVIDERS, UrlBuilderService,
provide(LocationStrategy, { useClass: HashLocationStrategy }),
provide('notification', { useClass: NotificationService })
]);
Any idea's?
Further Edit:
I now call the resolveAndCreate
like this:
var injector = Injector.resolveAndCreate([p[this.serviceName], Http]);
which failed with
No provider for ConnectionBackend! (UserService -> Http -> ConnectionBackend)
So i called it like this:
var injector = Injector.resolveAndCreate([p[this.serviceName], Http, ConnectionBackend]);
which failed with some other missing stuff.
Changed to this
var injector = Injector.resolveAndCreate([p[this.serviceName], HTTP_PROVIDERS]);
and now all is working.
What I do not understand is why it's not automatically resolving these components because i have them provided during bootstrap.
回答1:
You can achieve this by using system.js (that is loader used by angular2) by doing so:
System.import('path/to/UserService').then(m =>
{
//Here you can access user service and use it in injector etc.
Injector.resolveAndCreate([m.UserService]);
});
This technique is well illustrated in this article: Lazy Loading of Route Components in Angular 2
回答2:
new
To get components by name import the components like
import * as components from './components'
and access them with
var componentName = 'SomeComponent';
components[componentName]
See also this Plunker from Rob Wormald from https://github.com/angular/angular/issues/7596#issuecomment-198199074
old
With
Injector.resolveAndCreate(
you create a new injector that is entirely disconnected from the connector created from Angular using the providers passed to bootstrap(..., [Providers])
.
An injector created this way can only resolve providers passed to resolveAndCreate()
.
If you want to use the same injector as your Angular application, then you need to inject the injector
constructor(private injector:Injector) {
injector.get(...);
}
You can create a child injector from the passed injector and override bindings if you want. The child injector either resolves to the overridden bindings or walks up the parent injectors until root while trying to resolve requested dependencies.
来源:https://stackoverflow.com/questions/35436681/angular2-manually-resolve-a-type-by-string-name