Приложение Tab - Angular 6 - PullRequest
       18

Приложение Tab - Angular 6

0 голосов
/ 11 сентября 2018

У меня проблема с структурированием моего углового приложения. Мне нужно иметь приложение с вкладками вместо маршрутизации, а именно: всякий раз, когда пользователь нажимает на новую ссылку в приложении, вместо того, чтобы направлять приложение на этот компонент, оно будет:

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

Мой первоначальный план:

  1. чтобы удалить розетку из приложения и добавить [matTabNavBar].
  2. прослушивает любое изменение в маршруте и получает компонент и параметры, связанные с маршрутом.
  3. использовать маршрут в качестве ключа для вкладок (чтобы проверить, существует ли вкладка или нет).
  4. если компонента нет, динамически создайте новую вкладку и добавьте к ней компонент, а затем выберите эту вкладку.

Не могли бы вы помочь мне с этим, мне нужны руководящие принципы или лучшие практики для всех этапов (сбор идей). и если есть какие-то компоненты или пакеты, чтобы помочь мне достичь этого. спасибо

Редактировать: очистить пример,

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

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Я смог реализовать то, что хотел:

  1. удалить из приложения маршрутную розетку.
  2. добавить группу мат-табов вместо нее.
  3. прослушивание событий маршрутизации в приложении.
  4. получить необходимое имя компонента и параметр из маршрутизации.
  5. сохраните его в списке ключей, чтобы иметь возможность отслеживать, что открыто, и предотвращать открытие одного и того же компонента несколько раз (зависит от потребностей).
  6. загрузка компонента в пользовательском интерфейсе динамически с использованием * ngComponentOutlet
  7. передача параметров с использованием класса инъекции
  8. управлять событиями между вкладками, используя одноэтапный сервис инъекций с Obseravables.

вместо розетки

<mat-tab-group [selectedIndex]="selectedTab" backgroundColor="primary" color="primary" (selectedTabChange)="selectedTabChanged($event)" style="height:100%;">
      <mat-tab label="Dashboard">
        Dashboard Component -- none closable tab, does not depend on routing.
      </mat-tab>
      <mat-tab *ngFor="let tab of tabsComponents; index as i">
        <ng-template mat-tab-label>
          {{tab.title | translate}}
          <button mat-icon-button class="close-icon"
                  (click)="closeTab($event,i)">
            <mat-icon class="close-icon ">
              close
            </mat-icon>
          </button>
        </ng-template>
        <ng-container *ngComponentOutlet="tab.component; injector:tab.params" ></ng-container>
      </mat-tab>
    </mat-tab-group>

Прослушиватель событий при маршрутизации:

this.routerEventSub = router.events.pipe(filter(event => event instanceof NavigationEnd))
  .subscribe((routeChange: NavigationEnd) => {
    this.layout.adjustLayout({ route: routeChange.url });

    let child = route.snapshot.firstChild.firstChild;
    console.log(child);
    if (this.tabsKeys.indexOf(routeChange.url) == -1) {
      this.tabsKeys.push(routeChange.url);

      let myParams: iTechParam = {
        _params: child.params,
        _queryParam: child.queryParams,
        _path:router.url
      }
      let params = Injector.create([
        { provide: iTechParam, useValue: myParams }
      ], this.inj);
      this.tabsComponents.push({ title: child.data['title'], component: child.component, params: params, path: router.url });
      this.selectedTab = this.tabsKeys.length;
    } else {
      this.selectedTab = this.tabsKeys.indexOf(routeChange.url) + 1;//+1 is because the dashboard tab, none-closable one
    }


  });

Переменные:

tabsKeys: string[] = [];//store the keys of the opened tabs
tabsComponents: ITechTab[] = [];// stores information about the component in each tab
selectedTab = 0; // store the index of the selected tab

Закрыть вкладку по функциональности индекса:

closeTabByIndex(i: number) {
this.tabsKeys.splice(i, 1);
let removedtabs = this.tabsComponents.splice(i, 1);
if (this.router.url == removedtabs[0].path) {
  if (i == 0 && this.tabsComponents.length == 0) {
    this.router.navigate(['/dashboard']);
  } else {
    this.router.navigate([this.tabsComponents[i - 1].path]);
  }
}
}
0 голосов
/ 11 сентября 2018

Непонятно, почему вы думаете, что должны избавиться от маршрутизации, чтобы использовать навигацию по вкладкам. Вкладка навигации и маршрутизация не являются несовместимыми. Чтобы использовать MatTabNavBar и MatTabLink с маршрутизацией, настройте маршрутизацию приложения так, чтобы каждая «вкладка» представляла собой маршрут, добавьте параметры маршрутизатора к элементам mat-tab-link и используйте выход маршрутизатора для размещения содержимого вкладки. Это должно быть намного проще, чем вы запланировали, поскольку вам не нужно беспокоиться о «создании» динамического содержимого вкладки и использовании кнопки «Назад».

Вот код, выбранный из базового примера, полная демонстрация включена StackBlitz :

Template

<nav mat-tab-nav-bar [backgroundColor]="background">
    <a mat-tab-link routerLink="test-one" routerLinkActive #rla1="routerLinkActive" [active]="rla1.isActive">Test One</a>
    <a mat-tab-link routerLink="test-two" routerLinkActive #rla2="routerLinkActive" [active]="rla2.isActive">Test Two</a>
</nav>
<router-outlet></router-outlet>

Компоненты

import {Component} from '@angular/core';

/**
 * @title Basic use of the tab nav bar with routing
 */
@Component({
  selector: 'tab-nav-bar-basic-example',
  templateUrl: 'tab-nav-bar-basic-example.html',
  styleUrls: ['tab-nav-bar-basic-example.css'],
})
export class TabNavBarBasicExample {}

@Component({
  selector: 'test-one',
  template: '<p>Test One</p>'
})
export class TestOne {}

@Component({
  selector: 'test-two',
  template: '<p>Test Two</p>'
})
export class TestTwo {}

Модуль приложения

const appRoutes: Routes = [
  { path: '', redirectTo: 'test-one', pathMatch: 'full' },
  { path: 'test-one', component: TestOne },
  { path: 'test-two', component: TestTwo }
];

@NgModule({
  imports: [
    RouterModule.forRoot(
      appRoutes
    ),
    ...
  ],
  entryComponents: [TabNavBarBasicExample],
  declarations: [TabNavBarBasicExample, TestOne, TestTwo],
  bootstrap: [TabNavBarBasicExample],
  providers: []
})
export class AppModule { }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...