Is it possible to get type of component (Type<T>
) from string
value? Smth like:
let typeStr: string = 'MyComponent';
let type: any = resolveType(typeStr); // actual type
We have seen how Angular resolves dynamic components. The moduleProviderDef function is used to configure a provider for the Angular dependency injection framework. This is where ComponentFactory -s of dynamic components are passed to ComponentFactoryResolver class for resolution of a component's factory during runtime.
Passing a string value to a component from its class: Here, the message variable will get its value either from the constructor of the class or by using angular event bindings (user inputs). Example: It is the simplest way of passing a string to a component.
Understanding Components. In AngularJS, a Component is a special kind of directive that uses a simpler configuration which is suitable for a component-based application structure. This makes it easier to write an app in a way that's similar to using Web Components or using the new Angular's style of application architecture.
It also makes the controller's code much cleaner in contrast to fetching data inside the controller. Load only important data in resolves to render main parts of the page immediately and fetch all other data, asynchronously. In Angular1, we could see the following code to define resolves in router (ui-router):
Just in case anyone stumbles across this question like me. It is possible without maintaining a registry.
Full credit goes to yurzui for his solution.
Just a copy from there:
import { Type } from '@angular/core';
@Input() comp: string;
...
const factories = Array.from(this.resolver['_factories'].keys());
const factoryClass = <Type<any>>factories.find((x: any) => x.name === this.comp);
const factory = this.resolver.resolveComponentFactory(factoryClass);
const compRef = this.vcRef.createComponent(factory);
You can't do that without maintaining a "registry" for your classes.
interface Component { }
type ComponentClass = { new (): Component };
const REGISTRY = new Map<string, ComponentClass>();
function getTypeFor(name: string): ComponentClass {
return REGISTRY.get(name);
}
As for how to add entries to this REGISTRY
, you have a few options, here are two:
(1) Manually add it after every class definition:
class ComponentA implements Component { ... }
REGISTRY.set("ComponentA", ComponentA);
Or make a function for it:
function register(cls: ComponentClass): void {
REGISTRY.set(cls.name, cls);
}
class ComponentA implements Component { ... }
register(ComponentA);
(2) Use a decorator:
Just use the above register
function as a decorator:
@register
class ComponentA implements Component { ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With