Как сбросить/обновить данные тела вкладки в Angular Material, если пользователь переходит с одной вкладки на другую?

Вот мой пример кода

Главный контроллер

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

Любой простой способ добиться этого?


person Prashant Pimpale    schedule 03.04.2018    source источник
comment
Возможный дубликат Angular 2 Как отслеживать изменения вкладок   -  person David    schedule 03.04.2018
comment
@David Дэвид, я пробовал приведенный выше код, но он у меня не работает. Он напрямую переходит к новому маршруту, который мне не нужен. Необходимо оставаться на текущей вкладке, но данные должны обновляться после смены вкладки.   -  person Prashant Pimpale    schedule 03.04.2018
comment
Смотрите мой ответ, если это поможет   -  person David    schedule 03.04.2018


Ответы (3)


Если вы не хотите использовать параметры @Input, вы также можете использовать @ViewChild, чтобы получить ссылку на ваши дочерние компоненты, а затем вызвать метод этих компонентов для обновления данных.

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>
person David    schedule 03.04.2018
comment
Я пытался настроить его так, но this.surveyComponent не определен, поэтому обновление не запускается... есть идеи, почему? Хотя на бумаге мне кажется хорошо - person BHANG; 03.11.2020
comment
@BHANG Может быть, опубликовать новый вопрос с примером stackblitz - person David; 06.11.2020
comment
мой плохой, мои компоненты не были родитель-потомок ;-) спасибо за ответ, хотя - person BHANG; 07.11.2020

В угловом материале 8 есть возможность ленивой загрузки компонента во вкладках, когда пользователь выбирает его.

вы можете просто обернуть свой компонент для ленивой загрузки в ng-template, как показано в ссылке ниже

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

person Dattu Gaade    schedule 08.06.2019

Вы можете прочитать о типах взаимодействия компонентов здесь.

Вам нужно что-то вроде этого:

1. Дети -> родитель

В обоих компонентах нужен излучатель.

ГлавныйКонтроллер:

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

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

В компонентах определите эмиттер событий:

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

когда вы хотите вызвать сброс, напишите что-то вроде этого:

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

Это вызовет вызов в родительском методе this.update().

в этом методе вы можете определить другую логику для запуска сброса, но от родителя-потомка проще всего привязать объект данных, который вы можете изменить:

2. Родитель-> дети

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

в основных компах:

private surveyData: any;

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

в опросе комп:

@Input() private data: any;
person ForestG    schedule 03.04.2018
comment
Есть ли другой способ, кроме как выше? - person Prashant Pimpale; 03.04.2018
comment
комментарий ниже отражает это, хотя я не думаю, что это решение с чистым кодом. Кажется неправильным напрямую вызывать различные функции компонентов, поскольку, по моему мнению, они должны быть инкапсулированы внутри компонента и доступны через его интерфейс. - person ForestG; 03.04.2018
comment
Да, точно. Но я новичок в angular, поэтому не могу решить, какой из них лучше. Можете ли вы объяснить или какой-либо справочный код для комментария? Был бы признателен..! - person Prashant Pimpale; 04.04.2018
comment
Angular использует автоматическое обнаружение изменений в DOM. Если что-то вызывает его, он повторно отображает только часть документа - только те, которые, по мнению Angular, необходимо обновить, поскольку это ресурсоемкая и дорогостоящая операция. Чтобы сузить требуемые части повторного рендеринга, вы должны придерживаться официальных рекомендаций: от родителя к дочернему использовать прямую привязку, а от дочернего к родительскому использовать эмиттеры событий. Поскольку DOM представляет собой древовидное представление, следуя потоку этого дерева, вы можете добиться довольно быстрых обновлений. Источник - person ForestG; 04.04.2018
comment
этот ответ помог вам? - person ForestG; 05.04.2018
comment
Неа. До сих пор не в состоянии этого добиться. Я попробовал то, что предложил подход @David для временной цели. - person Prashant Pimpale; 05.04.2018
comment
@David, согласно документации Angular Material, я использовал вкладки и навигацию [material.angular.io/components/tabs/, которые делают то же самое, что Tab делает с параметром ссылки на маршрутизатор. Я должен опубликовать ответ на свой вопрос, но из-за меньшей репутации не могу этого сделать, как мне это отправить? - person Prashant Pimpale; 09.04.2018