Передача данных Angular между родительским и дочерним компонентом внутри панели навигации вкладки mat

#javascript #angular #typescript #angular-material

#javascript #angular #typescript #angular-материал

Вопрос:

Проект, над которым я работаю — https://stackblitz.com/github/NakoNachev/ExpenseTrackerWeb/tree/master/frontend .

Что у меня сейчас есть: группа вкладок mat с вкладками mat внутри компонента приложения. При нажатии на данную вкладку загружается определенный компонент. Большая часть имеющихся у меня данных загружается при запуске внутри приложения-компонента и передается дочерним компонентам, когда пользователь нажимает на заданную вкладку.

Что я хочу: в настоящее время ссылка остается неизменной, она не добавляет пути при нажатии на определенную вкладку mat. Из того, что я понял (я новичок в angular), мы можем определить пути панели навигации и использовать их для добавления их в качестве ссылки на вкладку mat.

Чего я не понимаю: у меня есть некоторые данные, которые передаются дочерним компонентам, но, похоже, я не нахожу, как я могу передать эти данные внутри ссылки вкладки mat. Чтобы быть более точным — я хочу создать панель навигации, которая при нажатии на определенную вкладку добавит путь (скажем, я нажимаю на datatable — ссылка изменяется на localhost: 4200 / datatable), загружает компонент и передает ему данные из родительского компонента. Прямо сейчас все вкладки mat находятся по одной ссылке, и в будущем я хочу добавить некоторые функции, которые должны будут перезагрузить некоторые конкретные пути.

Пример желаемого результата: пользователь заходит на веб-страницу, нажимает на вкладку datatable, путь меняется на localhost: 4200 / datatable, компонент приложения передал компоненту объект с данными для datatable, и он правильно отображается на вкладке datatable.

Моя текущая вкладка mat:

 
<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>
 

Что я пробовал в качестве кода:

 
<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>
 

Навигация работает, но я не знаю, как я могу передать данные (например, [expensesList]) через тег.

Заранее спасибо за помощь и извините, если вопрос уже задавался ранее, я пытался искать его столько, сколько мог, к сожалению, я ничего не нашел.

Ответ №1:

Почему вы выполняете вызов api в своем приложении-компоненте? Вы можете переместить этот код из компонента приложения в компонент таблицы данных в функции ngOnInit:

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

Затем вызов api будет выполняться только тогда, когда пользователь обращается к этой вкладке.

В качестве альтернативы, если вы хотите предварительно загрузить эти данные при начальной загрузке приложения, вам нужно будет сохранить результат вызова API в BehaviourSubject из библиотеки RXJS. Затем вы можете подписаться и получить данные из компонента data-table.

Редактировать: обновлен stackblitz для использования BehaviourSubjects https://stackblitz.com/edit/github-awefqi?file=src/app/services/api.service.ts

Я создал BehaviourSubject в api-сервисе и инициализировал с помощью тестового значения. Затем я вызываю apiService.getExpenses() в компоненте приложения.

Комментарии:

1. Изначально все было именно так, как вы догадались — я хотел предварительно загрузить данные и распределить их между различными компонентами, хотя, думаю, я перенесу их в компонент datatable,