[英]Typescript and Angular: Type a string to a component class
a function is passing the name of my component via a string but I need it to be the actual component class: 一个函数通过字符串传递组件的名称,但是我需要它成为实际的组件类:
Current: "MyComponent" Need: MyComponent 当前:“ MyComponent”需要:MyComponent
I need to "convert" it so It's passing correctly. 我需要对其进行“转换”,以便正确传递。 I have an
ngFor
that spits out values and I'm trying to use piping to convert it: 我有一个
ngFor
,它吐出值,并且我试图使用管道将其转换:
<div id="grid">
<gridster [options]="options">
<gridster-item [item]="item" *ngFor="let item of dashboard;let i = index;">
<div class="grid-header drag-handle">
<span class="handle-icon"><i class="material-icons">open_with</i></span>
<span class="close-icon" (click)="removePanel(item)"><i class="material-icons">close</i></span>
</div>
<div class="grid-content">
<ndc-dynamic [ndcDynamicComponent]="item.viewType | dynamicComponent"></ndc-dynamic>
</div>
</gridster-item>
</gridster>
</div>
Above it's item.viewType
that's a strong coming from my item array. 在它上面的
item.viewType
是我的item数组的强项。 I'm passing the value to a dynamicComponent
custom pipe. 我将值传递给
dynamicComponent
自定义管道。 I have my components imported into my dynamic-component.pipe.ts
. 我将组件导入到
dynamic-component.pipe.ts
。 I just need to change the string to the specified viewType
and return the typed
value: 我只需要将字符串更改为指定的
viewType
并返回typed
值:
import { Pipe, PipeTransform } from '@angular/core';
//pulling in all the possible components
import * from '../../views';
@Pipe({
name: 'dynamicComponent'
})
export class DynamicComponentPipe implements PipeTransform {
transform(value: string): any {
}
}
You'll need to manually create a mapping between string values and the components. 您需要手动在字符串值和组件之间创建映射。 Components are actually named functions which can be minimized to shorter variable names when compiling for production.
组件实际上是命名函数,在进行生产编译时可以将其最小化为较短的变量名。
import ComponentA from '../views/ComponentA';
import ComponentB from '../views/ComponentA';
const componentMap = {
'ComponentA': ComponentA,
'ComponentB': ComponentB
};
@Pipe({name: 'dynamicComponent'})
export class DynamicComponentPipe implements PipeTransform {
transform(value: string): any {
if(componentMap[value]) {
return componentMap[value];
}
throw new Error(`${componentMap} component was not found`);
}
}
UPDATED: 更新:
The problem with using the name of a component at runtime is that it can be minimized into a smaller variable name for production. 在运行时使用组件名称的问题在于,可以将其最小化为较小的变量名称以进行生产。 Therefore, doing something like
views['MyComponent']
won't work later when MyComponent
is renamed to something like a12
. 因此,将
MyComponent
重命名为a12
东西之后,执行诸如views['MyComponent']
将无法正常工作。
An alternative approach is to use the component's selector string value to select the component. 另一种方法是使用组件的选择器字符串值选择组件。 Each component in Angular has to be a unique selector string.
Angular中的每个组件都必须是唯一的选择器字符串。 So this is a safe value to use as a key.
因此,这是用作密钥的安全值。
You can access (at least in Angular 5) the component's metadata via the __annotations__
property. 您可以通过
__annotations__
属性访问(至少在Angular 5中)组件的元数据。 This property is an array that contains a the metadata. 此属性是一个包含元数据的数组。
So you could try something like: 因此,您可以尝试执行以下操作:
import * as views from '../views';
@Pipe({name: 'dynamicComponent'})
export class DynamicComponentPipe implements PipeTransform {
transform(value: string): any {
const view = views.filter((component)=>component['__annotations__'][0]['selector'] === value));
if(view) {
return view;
}
throw new Error(`A component with selector "${value}" was not found`);
}
}
Furthermore, you could drop the need for a views
file by accessing the ngModule
directly and iterating all components to find a matching selector. 此外,您可以通过直接访问
ngModule
并迭代所有组件以找到匹配的选择器来减少对views
文件的需求。 Modules will have the same __annotations__
property. 模块将具有相同的
__annotations__
属性。
I did this pretty simple way: 我这样做很简单:
I created a views.ts
with all of my views exported at the root of my views directory. 我创建了一个
views.ts
并将所有视图导出到我的views目录的根目录。 Then in directory that my pipe is being used I imported the views
using: 然后在使用管道的目录中,使用以下命令导入
views
:
import * as views from '../../views/views'
Then in my transform
method I return views[value];
然后,在我的
transform
方法中,我return views[value];
where value
is the string being pulled in from my template. 其中
value
是从模板中提取的字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.