简体   繁体   中英

Angular pass data between parent and child component inside mat tab nav bar

The project i am working on - https://stackblitz.com/github/NakoNachev/ExpenseTrackerWeb/tree/master/frontend .

What i currently have : A mat tab group with mat tabs inside the app-component. Upon click on a given tab, a specific component is being loaded. Most of the data i have is loaded on start inside the app-component and passed to the child components when the user clicks on a given tab.

What i want : Currently the link stays the same, it does not add paths upon clicking on a specific mat tab. From what i understood (i am new to angular), we can define navbar paths and use these to add them as a mat tab link.

What i don't undertand : I have some data that is being passed to the child components, but i don't seem to find how i can pass that data inside the mat tab link. To be more precise - i want to create a nav bar, which, upon clicking on a certain tab, will append the path ( say i click on datatable - the link is being changed to localhost:4200/datatable), load the component and pass data to it from the parent component. Right now all the mat tabs are under the same link and i the future i want to add some features that will have to reload some specific paths.

Example of desired outcome : User enters the webpage, clicks on datatable tab, path changes to localhost:4200/datatable, the app-component passed a object with the data for the datatable to the component and it is correctly shown under the datatable tab.

My current mat tab:


<mat-tab-group animationDuration="0" (selectedTabChange)="onTabChanged($event)">
<mat-tab label="Add Expense" routerLink="/input">
  <app-expense-input [badgeCounter] = "badgeCounter" (countChanged)="countChangedHandler($event)"></app-expense-input> 
</mat-tab>

<mat-tab >
  <ng-template mat-tab-label>
    <span matBadge={{badgeCounter}} matBadgeOverlap="false" matBadgeColor="accent">Datatable</span>
  </ng-template>
  <ng-template matTabContent>
  <app-data-table [expensesList] = "expensesList" [badgeCounter] = "badgeCounter" 
  (countChanged)="countChangedHandler($event)"
  (countReset)="countResetHandler($event)"></app-data-table>
</ng-template>
</mat-tab>

<mat-tab label = "Chart">
    
  <ng-template matTabContent>
    <app-highcharts></app-highcharts>
  </ng-template>
</mat-tab>

</mat-tab-group>

What i have tried as code:


<nav mat-tab-nav-bar [backgroundColor]="background">
  <a mat-tab-link routerLink ="/input"> Input</a>
  <a mat-tab-link routerLink ="/datatable">Datatable</a>
  <a mat-tab-link routerLink="/chart">Chart</a>
</nav>

Navigation works, but i don't know how i can pass the data( for example the [expensesList]) via the tag.

Thanks in advance for the help and sorry if the question has already been asked before, i tried to look for it as much as i could, unfortunately i didnt find anything.

Why are you making the api call in your app-component? You could move this code from the app-component to the data-table component in the ngOnInit function:

this.apiService.getExpenses()
.subscribe(data => this.expensesList = data);

Then, the api call will only be made when a user accesses that tab.

Alternatively, if you DO want to preload this data when the app initially loads, you would need to store the result of the API call in a BehaviourSubject from the RXJS library. Then you can subscribe and grab the data from the data-table component.

Edit: Updated stackblitz to use BehaviourSubjects https://stackblitz.com/edit/github-awefqi?file=src/app/services/api.service.ts

I created a BehaviourSubject in the api-service, and initialized with a test value. Then I call the apiService.getExpenses() in the app-component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM