Вкладка Angular Material: предотвращение изменения вкладки mat-tab-group, если форма на текущей вкладке грязная

Я пытался предотвратить изменение вкладки mat-tab, если форма на текущей активной вкладке грязная.

Но я не мог найти способ перехватить событие смены вкладки.

<mat-tab-group>

  <mat-tab label="Tab 0" >

    // Tab 0 Content

  </mat-tab>

  <mat-tab label="Tab 1"  >

    // Tab 1 Content

  </mat-tab>

  <mat-tab label="Tab 2" >

    // Tab 2 Content

  </mat-tab>

</mat-tab-group>

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

У меня есть хитрость, чтобы это стало возможным. Просто разместите здесь, чтобы помочь, если кто-то столкнется с тем же.


person jophab    schedule 15.06.2019    source источник


Ответы (1)


Это решение - просто обходной путь, и у него есть свои недостатки. Об этом говорится ниже.

Шаги:

В шаблоне:

  1. Отключить все вкладки группы mat-tab-group <mat-tab label="Tab 0" disabled>

  2. Предоставьте обработчик события щелчка для mat-tab-group. Также установите свойство selectedIndex, используя переменную из класса компонента.

    <mat-tab-group (click)="tabClick($event)" [selectedIndex]="selectedTabIndex">

В классе Component:

  1. Объявить переменную selectedTabIndex
    selectedTabIndex = 0;

  2. Создайте метод для получения индекса вкладки при наличии метки вкладки.

     getTabIndex(tabName: string): number {
    
     switch (tabName) {
       case 'Tab 0': return 0;
       case 'Tab 1': return 1;
       case 'Tab 2': return 2;
       default: return -1; // return -1 if clicked text is not a tab label text
      }
    
     }
    

    Мы можем получить текст метки табуляции из свойства события щелчка

    `clickEventName.toElement.innerText`
    
  3. Создайте метод обработки события щелчка на mat-tab-group.

     tabClick(clickEvent: any) {
    
     // Get the index of clicked tab using the above function
     const clickedTabIndex = this.getTabIndex(clickEvent.toElement.innerText);
    
     // if click was not on a tab label, do nothing
     if (clickedTabIndex === -1) {
       return;
     }
    
     // if current tab is same as clicked tab, no need to change. 
     //Otherwise check whether editing is going on and decide
    
     if (!(this.selectedTabIndex === clickedTabIndex)) {
    
       if ( /*logic for form dirty check*/ ) {
    
         // if form is dirty, show a warning modal and don't change tab.
       }
       else {
    
         // if form is not dirty, change the tab
         this.selectedTabIndex = clickedTabIndex;
       }
     }
    

    }

В моем случае содержимое каждой вкладки находилось в отдельных компонентах. Поэтому я использовал @ViewChild, чтобы получить к ним доступ и проверить, не загрязнена ли какая-либо форма.

Недостатки:

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

    Таким образом, это может вызвать смену вкладки. Вы можете найти другие свойства в событии щелчка, чтобы предотвратить этот сценарий, если это возможно. Я использовал следующий код в начале tabClick() метода

     if (!((clickEvent.toElement.className).toString().includes('mat-tab-label'))) {
      return;
      }
    
  2. Вам может потребоваться переопределить css of disabled состояние mat-tab, чтобы оно выглядело естественно

Шаблон:

<mat-tab-group  (click)="tabClick($event)" [selectedIndex]="selectedTabIndex">

  <mat-tab label="Tab 0" disabled>

    // Tab 0 Content

  </mat-tab>

  <mat-tab label="Tab 1"  disabled>

    // Tab 1 Content

  </mat-tab>

  <mat-tab label="Tab 2"  disabled>

    // Tab 2 Content

  </mat-tab>

</mat-tab-group>
person jophab    schedule 15.06.2019
comment
Было бы очень полезно .. Если вы можете добавить ссылку на stackblitz вышеупомянутого решения. - person abhigyan nayak; 08.05.2020
comment
Это отлично работает в Chrome, но получение ERROR TypeError: clickEvent.toElement не определено в Firefox. может кто-нибудь посоветовать, как это исправить? // Эта строка вызывает проблему const clickedTabIndex = this.getTabIndex (clickEvent.toElement.innerText); - person redsam; 30.09.2020