基于数据的不同ChildComponent

问题描述 投票:2回答:2

如何根据从数据库中获取的数据更改组件? 我正在使用这样的东西: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: '',...},
]
angular angular-components
2个回答
1
投票

AngularJS中,可能只使用组件标记编译组件,如:<comp></comp>,如果它是字符串。

但在新的Angular不幸还没有。我看了ComponentFactoryResolverngComponentOutlet API。他们只接受Type<T> resolveComponentFactory,其中T是一些组件/指令......类。

所以你不能将组件选择器作为字符串传递。

作为解决方案类型:

  • 创造qazxsw poi。 qazxsw poi - type,qazxsw poi - component type 并在模板中迭代数据: Map<string, any>()
  • 创建方法key。这里有一些搜索逻辑。模板: any

1
投票

如何使用<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>

ngComponentOutlet

© www.soinside.com 2019 - 2024. All rights reserved.