如何根据从数据库中获取的数据更改组件? 我正在使用这样的东西:stackblitz 但是根据用户角色显示工具。 (数据库返回哪些工具,订单等)
我有两种方法可以考虑如何做到这一点:
第一
使用*ngIf
像:
<div class="tools-wrapper controls">
<div class="tools-container">
<app-tool-menu *ngIf="existsInData('menu')"></app-tool-menu>
<mat-divider *ngIf="existsInData('menu')"></mat-divider>
<app-tool-refresh *ngIf="existsInData('refresh')"></app-tool-refresh>
<app-tool-info *ngIf="existsInData('info')"></app-tool-info>
<app-tool-edit *ngIf="existsInData('edit')"></app-tool-edit>
</div>
</div>
这不够动态。
第二次使用factoryResolver
@Injectable()
export class InjectorService {
constructor(private factoryResolver: ComponentFactoryResolver) { }
setRootViewContainerRef(viewContainerRef) {
this.rootViewContainer = viewContainerRef;
}
addDynamicComponents(data: any[]) {
const component = factory.create(this.rootViewContainer.parentInjector);
data.forEach((tool) => {
const toolComponent = this.toolMapping(tool);
const factory = this.factoryResolver.resolveComponentFactory(toolComponent);
this.rootViewContainer.insert(component.hostView);
});
}
toolMapping(tool) {
const tools = {
'menu': MenuComponent,
'refresh': RefreshComponent,
'info': InfoComponent,
'edit': EditComponent,
};
return tools[tool];
}
}
@Component({
selector: 'my-app',
template: `
<h1>Hello {{name}}</h1>
<ng-template #dynamic></ng-template>
`
})
export class AppComponent implements OnInit {
name = 'from Angular';
@ViewChild('dynamic', { read: ViewContainerRef })
viewContainerRef: ViewContainerRef;
constructor(private service: InjectorService ) {}
ngOnInit() {
this.service.setRootViewContainerRef(this.viewContainerRef);
this.service.addDynamicComponents(.. data ..);
}
}
那么这段代码就有很多开销,比如为我拥有的每个类似构造定义一个toolMapping或创建一个Service。
有更好,更清洁的解决方案吗?
数据看起来像这样(必要时可以修改):
[
{type: 'menu', tooltip: '', ...},
{type: 'divider', tooltip: '',...},
{type: 'refresh', tooltip: '', ...},
{type: 'info', tooltip: '',...},
{type: 'edit', tooltip: '',...},
]
在AngularJS
中,可能只使用组件标记编译组件,如:<comp></comp>
,如果它是字符串。
但在新的Angular
不幸还没有。我看了ComponentFactoryResolver
,ngComponentOutlet
API。他们只接受Type<T>
resolveComponentFactory,其中T
是一些组件/指令......类。
所以你不能将组件选择器作为字符串传递。
作为解决方案类型:
Map<string, any>()
key
。这里有一些搜索逻辑。模板:
any
如何使用<ng-container *ngFor="let itm of data">
<ng-container *ngComponentOutlet="someMap.get(itm.type)">
</ng-container>
</ng-container>
与getComponentType(type: string)
?它比<ng-container *ngFor="let itm of data">
<ng-container *ngComponentOutlet="getComponentType(itm.type)">
</ng-container>
</ng-container>
解决方案简洁得多。
<ng-container>