1

I have the following HTML code:

<pm-application [node]="node" *ngIf="node.type ==='application'"></pm-application>
<pm-proxy [node]="node" *ngIf="node.type ==='proxy'"></pm-proxy>
<pm-part [node]="node" *ngIf="node.type ==='part'"></pm-part>
<pm-certificate [node]="node" *ngIf="node.type ==='certificate'"></pm-certificate>
<pm-portal [node]="node" *ngIf="node.type ==='portal'"></pm-portal>

It does not look nice and there are many other types so the list will grow. Is there an easier way? Something like:

<{{node.type}} [node]="node"><{{node.type}}>
Galdor
  • 1,636
  • 4
  • 23
  • 37

2 Answers2

1

You could use a component like

beta.17

@Component({
  selector: 'dcl-wrapper',
  template: '', //`<div #target></div>`
})
export class DclWrapper {
  // alternative way of getting a `ViewContainerRef` for an element inside the view instead of the host itself
  //@ViewChild('target', {read: ViewContainerRef}) target;

  constructor(private dcl:DynamicComponentLoader, private target:ViewContainerRef) {}
  @Input() type;

  ngOnChanges() {
    if(this.cmpRef) {
      throw 'currently changing type after the component was added is not supported'
    }
    this.dcl.loadNextToLocation(this.type, this.target).then((cmpRef) => {
      this.cmpRef = cmpRef;
    });
  }
}

Plunker beta.17

!! <= beta.15 syntax !!

@Component({
  selector: 'dcl-wrapper',
  template: `<div #target></div>`
})
export class DclWrapper {
  constructor(private elRef:ElementRef, private dcl:DynamicComponentLoader) {}
  @Input() type;

  ngOnChanges() {
    if(this.cmpRef) {
      this.cmpRef.dispose();
    }
    this.dcl.loadIntoLocation(this.type, this.elRef, 'target').then((cmpRef) => {
      this.cmpRef = cmpRef;
    });
  }
}

(from Angular 2 dynamic tabs with user-click chosen components)

Then in your component use it like

@Component({  
  directives: [DclWrapper],
  template: `
  <dcl-wrapper [type]="types[node.type]"></dcl-wrapper>
`})
export class ParentComponent {
  types = {
    application: PmApplicationComponent,
    proxy: PmProxyComponent,
    part: PmPartComponent,
    certificate: PmCertificateComponent,
    portal: PmPortalComponent,
  };
}

You can't use binding like [node]="node" for components added DynamicComponentLoader but you can pass data to DclWrapper and pass the data imperatively to the wrapped component. If this approach seems interesting to you I can elaborate a bit more.

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Since DynamicComponentLoader is deprecated, I wait for a more stable and better documented solution. – Galdor May 19 '16 at 12:34
  • The current method is explained in http://stackoverflow.com/questions/36325212/angular-2-dynamic-tabs-with-user-click-chosen-components/36325468#36325468 – Günter Zöchbauer May 20 '16 at 17:39
0

I'm not exactly sure if this is possible in Angular 2 but in v1 you could use restrict property in directives to use a css class or attribute instead of the node name.

If this is not possible I'd just create a super-component

<pm-supercomponent [node]="node"/>

and have the switch inside this component. Then at least you don't need to repeat it all the time.

damien
  • 23
  • 3