0
votes

I'm new Angular using Angular 6.0.0-beta. I'm not able to append dynamic-component to the dynamic anchor as explained below: -

I have placed anchor(appContent) like this in html: -

    <mat-card>
    <mat-card-content>
        <mat-tab-group class="tab-group" (selectedTabChange)="onTabChanged($event)">
            <mat-tab *ngFor="let obj of tags">
                <ng-template mat-tab-label>{{ obj.name }}</ng-template>
                <div class="tab-content" appContent>
                    {{ obj.name }}
                </div>
            </mat-tab>
        </mat-tab-group>
    </mat-card-content>
    </mat-card>

I'm using below code to append to ContentComponent to the appContent, I'm not adding piece of code which create TagId and Array(Content) Mapping : -

  private tags: Array<Tag>;
  private currentTag: Tag;
  // private contents: Array<Content>;
  private tagContentsMap: Map<number, Array<Content>>;

  onTabChanged(event: MatTabChangeEvent) {
    this.currentTag = this.tags[event.index]; // fetching current tag from the Tags Array
    this.loadContentForTag(this.currentTag);
  }

  private loadContentForTag(tag: Tag) {
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(ContentComponent);
    const viewContainerRef = this.contentsDirective.viewContainerRef;
    viewContainerRef.clear();
    const componentRef = viewContainerRef.createComponent(componentFactory);

    console.log(tag);
    console.log(this.tagContentsMap.get(tag.tagId)); // I can see content array here on tab change
    (<ContentComponent>componentRef.instance).contentList = this.tagContentsMap.get(tag.tagId); // On assigning content array here is not reflecting in the HTML of ContentComponent
  }

ContentComponent is as below: -

import { Component, OnInit } from '@angular/core';
import { Content } from '../../models/flat/content';

@Component({
  selector: 'app-content',
  template: `
  <p *ngFor="let content of contentList">
    {{ content.title }}
  </p>
`,
  styleUrls: ['./content.component.scss']
})
export class ContentComponent implements OnInit {
  contentList: Array<Content>;

  constructor() { }

  ngOnInit() {
  }

}

So now the problem is, tabs getting created dynamically and appContent vary with current Tab. For the First auto selected tab ContentComponent reflects the data in (div class="tab-content" appContent) but on changing tabs it's not reflecting data of the current tab's even though anchor(appContent) is available.

Please help me resolve this. Thank you in advance.

1

1 Answers

1
votes

I think you're complicating this a bit too much. I mean, why are you using dynamic components? You are always adding/removing the same component (ContentComponent). It would be much easier to just inject that component, and bind its contentList property to the content you want to show (I don't know the selector for ContentComponent os I', assuming itscontent`):

<mat-card>
    <mat-card-content>
        <mat-tab-group class="tab-group" (selectedTabChange)="onTabChanged($event)">
            <mat-tab *ngFor="let obj of tags">
                <ng-template mat-tab-label>{{ obj.name }}</ng-template>
                <div class="tab-content" appContent>
                    <content [contentList]="tagContent"></content>
                    {{ obj.name }}
                </div>
            </mat-tab>
        </mat-tab-group>
    </mat-card-content>
</mat-card>

Now, in the component:

private tags: Array<Tag>;
private currentTag: Tag;
private contentTag: Array<Content>;
// private contents: Array<Content>;
private tagContentsMap: Map<number, Array<Content>>;

onTabChanged(event: MatTabChangeEvent) {
    this.currentTag = this.tags[event.index]; // fetching current tag from the Tags Array
    this.tagContent = this.tagContentMap.get(this.currentTag.tagId);
}

As you see, much easier. You can also add an ngIf to the <content ...></content> tag so you can hide that component if tagContent is empty or null (don't know if this is possible)