Javascript Typescript和Angular:为组件类键入字符串
函数通过字符串传递组件的名称,但我需要它是实际的组件类: 当前:“MyComponent” 需要:MyComponent 我需要“转换”它,使其正确通过。我有一个Javascript Typescript和Angular:为组件类键入字符串,javascript,angular,typescript,Javascript,Angular,Typescript,函数通过字符串传递组件的名称,但我需要它是实际的组件类: 当前:“MyComponent” 需要:MyComponent 我需要“转换”它,使其正确通过。我有一个ngFor,可以输出值,我正在尝试使用管道来转换它: <div id="grid"> <gridster [options]="options"> <gridster-item [item]="item" *ngFor="let item of dashboard;let i = index
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>
我这样做很简单: 我创建了一个
views.ts
,将所有视图导出到我的视图目录的根目录下。然后在使用管道的目录中,我使用以下方法导入了视图
:
import*作为来自“../../views/views”的视图
然后在我的transform
方法中,我返回视图[值]
其中value
是从我的模板中拉入的字符串。您需要手动创建字符串值和组件之间的映射。组件实际上是命名函数,在编译用于生产时,可以将其最小化为更短的变量名
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`);
}
}
更新:
在运行时使用组件名称的问题在于,可以将其最小化为一个较小的变量名用于生产。因此,当MyComponent
被重命名为a12
时,执行类似于views['MyComponent']
的操作将不起作用
另一种方法是使用组件的选择器字符串值来选择组件。Angular中的每个组件都必须是唯一的选择器字符串。所以这是一个安全值,可以用作密钥
您可以通过\uuuu annotations\uuu
属性访问(至少在Angular 5中)组件的元数据。此属性是包含元数据的数组
因此,您可以尝试以下方法:
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`);
}
}
此外,通过直接访问ngModule
并迭代所有组件以找到匹配的选择器,您可以不再需要views
文件。模块将具有相同的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu注释属性。可能会检查一下,我对angular2是个新手,但我还没有完全掌握如何将其与我的管道
联系起来。当JavaScript最小化且函数名缩短时,这不会在生产中出现中断。我将使用'_(ツ)_/''我正在通过使用export
将可能的组件放入一个ts
文件中,然后使用“../../views/views”中的import*作为视图将它们导入到我的pipe
文件中;
这会返回一个已经包含键值对的数组。我不能继续使用它吗?仅供参考,我不是说你不知道你错了。只需询问是否可以从上面的导入中使用视图
,因为它已经是一个数组,并且视图[值]
返回与上面相同的内容。我认为视图
中的键将是生产中的最小化版本。只需运行控制台.log(视图)
从生产构建中查看我是否正确。我看到了问题所在。当其他人开始在此系统中工作时,列出管道文件中的每个组件可能会有点繁重。视图
目录中的视图.ts
文件用于提供单个导出点。您建议如何解决此问题?@dcp3450将字符串值赋给项。viewType
?您可以控制这些值是什么吗?
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`);
}
}