How to reset/refresh tab body data in Angular Material if user move from one tab to another tab?

22,739

Solution 1

If you don't want to use @Input parameters, you can also use @ViewChild to get a reference to your child components and then call a method on these components to refresh the data

component.ts

  import {ViewChild} from '@angular/core';
  import { MatTabChangeEvent } from '@angular/material';
  //...
  @ViewChild(PollComponent) private pollComponent: PollComponent;
  @ViewChild(SurveyComponent) private surveyComponent: SurveyComponent;


  //...
  onTabChanged(event: MatTabChangeEvent) 
  {
    if(event.index == 0)
    {
        this.pollComponent.refresh();//Or whatever name the method is called
    }
    else
    {
        this.surveyComponent.refresh(); //Or whatever name the method is called
    }
  }

component.html

<mat-tab-group id="report" (selectedTabChange)="onTabChanged($event)">

</mat-tab>

Solution 2

In angular material 8, there is an option for lazy loading the component in tabs when user selects it.

you can simply wrap your component to be lazy loaded in ng-template as shown in link below

https://material.angular.io/components/tabs/overview#lazy-loading

Solution 3

You can read about component interaction types here.

You need something like this:

1. Children -> parent

In both of the components, have an need an emitter.

MainController:

  <app-poll (changed)=this.update($event)></app-poll>

  <app-survey (changed)=this.update($event)></app-survey>

In the components, have an event emitter defined:

@Output() changeEmitter = new EventEmitter<any>();

when you want to trigger the reset, write something like this:

changedEmitter.emit(<<you can insert objects here>>);

This will trigger the call in their parent's this.update().

in that method, you can define other logic to trigger a reset, but from parent-child, the easiest way is to bind a data object, which you can change:

2. Parent-> children

  <app-survey (changed)=this.update(newValue) [data]="surveyData"></app-survey>

in the main comp ts:

private surveyData: any;

update(newValue: any){
  surveyData =  <<something>>
}

in the survey comp:

@Input() private data: any;
Share:
22,739
Prashant Pimpale
Author by

Prashant Pimpale

[email protected] Read this, when I did, at that time the count was 35! Must Read Favorite Question Favorite Answer

Updated on June 09, 2020

Comments

  • Prashant Pimpale
    Prashant Pimpale about 4 years

    Here is my sample code

    Main Controller

    <mat-tab-group id="report">
    <mat-tab label="Poll">
    <div class="demo-tab-content">
      <app-poll></app-poll>
    </div>
    
    </mat-tab>
    <mat-tab label="Survey">
    <div class="demo-tab-content">
      <app-survey></app-survey>
    </div>
    </mat-tab>
    

    In each tab, there is different controller named - Poll and Survey. Here I want to refresh\reset one tab data if the user moves from one to another.

    Any simple way to achieve that?

  • Prashant Pimpale
    Prashant Pimpale about 6 years
    Is there any other way than above one?
  • ForestG
    ForestG about 6 years
    the comment below reflects to that, although I do not think that that solution is clean-code. It feels wrong to call a different components functions directly, as it is supposed to be encapsulated iside the component and accessed via it's interface in my opinion.
  • Prashant Pimpale
    Prashant Pimpale about 6 years
    Yes exactly. But I am new to angular hence I am not able to decide which one is better. Can you explain or any reference code for about comment? It would be grateful..!
  • ForestG
    ForestG about 6 years
    Angular uses an automatic change detection in the DOM. If somhing triggers it, it re-renders only part of the document - only the ones, Angular think it needs to update as it is a resource-heavy and costly operation. To narrow down the required re-rendering parts, you should stick to the official recommendations: from parent to child use direct binding, and from children to parent use event emitters. As the DOM is a tree representation, following the flow of that tree, you can achive quite fast updates. Source
  • ForestG
    ForestG about 6 years
    did this answer help you?
  • Prashant Pimpale
    Prashant Pimpale about 6 years
    Nope. Still not able to achieve that. I have tried what suggested by @David approach for the temporary purpose.
  • Prashant Pimpale
    Prashant Pimpale about 6 years
    @David as per documentation of an Angular Material I have used Tabs and navigation [material.angular.io/components/tabs/… which exactly do the same thing what Tab does with the router link parameter. I have to post an answer to my own question but due to less reputation not able to do that how do i submit that?
  • BHANG
    BHANG over 3 years
    I've tried setting it up like this but this.surveyComponent is not defined, so the refresh doens't get triggered... any idea why? Looks good on paper to me though
  • David
    David over 3 years
    @BHANG Maybe post a new question with a stackblitz exemple
  • BHANG
    BHANG over 3 years
    my bad, my components weren't parent-child ;-) thanks for replying though