Angular2, manually resolve a type by string/name

廉价感情. 提交于 2019-12-24 02:12:46

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!