1

I'd like to conditionally display a child component (including its ContentChildren) within a parent component's template.

app.component.html

<parent>
  <child #initial>
    <span>Player</span>
  </child>
  <child label="Intro">
    <span>Intro</span>
  </child>
  <child label="Content">
    <span>Content</span>
  </child>
</tabs>

desired result

<parent>
  <child>
    <span>Player</span>
  </child>
</parent>

parent.component.ts

@Component({
  selector: 'parent',
  template: `<!--Display {{current}} and its ContentChildren-->`,
  styleUrls: ['./tabs.component.scss']
})

export class ParentComponent implements OnInit {
  @ContentChildren(ChildComponent) childs;
  @ContentChild("initial") initial;
  @ContentChild("open") current;
  ngOnInit(): void {
    if (this.initial) this.current = this.initial;
  }
}

child.component.ts

@Component({
  selector: 'child',
  template: `<ng-content></ng-content>`,
})

export class ChildComponent {
  @Input() label: string;
}

Attempt for parent.component.html

<ng-container *ngFor="let child in childs">
  <child *ngIf="child == current"></child> //ContentChildren as defined in 'app.component.html' are lost now 
</ng-container>
Kode Bryant
  • 511
  • 8
  • 23
  • @Vega Yes, exactly – Kode Bryant Aug 24 '17 at 16:24
  • and you don't want to use ngif or ngswitch.. ? – Vega Aug 24 '17 at 16:25
  • @Vega It works witch ngIf, but the child component's is lost – Kode Bryant Aug 24 '17 at 16:26
  • @Vega What do you mean exactly? – Kode Bryant Aug 24 '17 at 16:31
  • @Vega I've tried so, but as the ContentChildren of child are defined outside of the parent component, they must remain dynamic. I've added my attempt with a wrapper in the question – Kode Bryant Aug 24 '17 at 16:40
  • @Vega I'm not sure how it should word with ng-template. Basically I would need to iterate over ng-content and display the child if it is equal to current. But no idea how/if this works – Kode Bryant Aug 24 '17 at 17:02
  • Would you consider using routing instead? It is set up to display one set of elements at a time from multiple choices. So Player, Intro, and Content would all be routes and only one would be displayed at a time. I have a tabbed edit dialog and use routes to route to the content of each tab. – DeborahK Aug 24 '17 at 20:13

1 Answers1

1

You can do by usingngSwitch.

<parent>
  <div [ngSwitch]="current">
      <child1 *ngSwitchCase="'Intro'" label="Intro">
          <span>Intro</span>
      </child1>

      <child2 *ngSwitchCase="'Content'" label="Content">
          <span>Content</span>
      </child2>
  </div>
</parent>

If you don't want the ngSwitch and need to change the entire template dynamically, hope the following answer will be helpful Dynamic template URLs in Angular 2 Ask

Rajez
  • 3,717
  • 1
  • 14
  • 21