首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >选项卡应用-角6

选项卡应用-角6
EN

Stack Overflow用户
提问于 2018-09-11 14:56:56
回答 2查看 2K关注 0票数 2

我正面临着构造我的角度应用程序的问题。我需要一个选项卡应用程序而不是路由,即:每当用户单击应用程序中的新链接,而不是将应用程序路由到该组件时,它将:

  1. 检查选项卡是否已打开,然后选择它。
  2. 如果未打开,则向导航选项卡中的选项卡列表中添加一个新选项卡并选择它。
  3. 每当用户单击该选项卡时,路由器将更改为新选项卡。
  4. 在浏览器中回击时,系统将选择前一个选项卡,或打开最后一个已关闭的选项卡。

我最初的计划是:

  1. 若要从应用程序中删除出口并添加matTabNavBar,请执行以下操作。
  2. 侦听路由中的任何更改,并获取与路由相关的组件和参数。
  3. 使用路由作为选项卡的键(检查选项卡是否已经存在)。
  4. 如果组件不存在,则动态创建一个新选项卡并将组件添加到其中,然后选择该选项卡。

请你帮我这一点,我需要指南或最佳实践的所有步骤(收集意见)。如果有一些组件或软件包帮助我实现这一点。谢谢

编辑:要清除示例,

假设我有一个从数据库加载的系统中的项目列表,当我想编辑一个项目时,我将能够在它自己的选项卡中打开它。所以我可以同时打开多个项目。当我通过新选项卡添加一个新项时,我也应该能够在它自己的选项卡中打开该记录。它们不仅仅是我想在它们之间路由的静态选项卡的列表。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-14 14:59:37

我能够通过以下方式实现我的愿望:

  1. 从应用程序中移除路由出口。
  2. 添加一个Mat-选项卡组而不是它。
  3. 收听应用程序中的路由事件。
  4. 从路由中获取所需的组件名称和参数。
  5. 将其存储在一个键列表中,以便能够跟踪打开的内容,并防止多次打开相同的组件(取决于需要)。
  6. 使用*ngComponentOutlet动态加载UI中的组件
  7. 使用可注入类传递参数
  8. 使用带有可观察性的单例注入服务管理选项卡之间的事件。

而不是出口

代码语言:javascript
复制
<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>

路由上的事件侦听器:

代码语言:javascript
复制
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
    }


  });

变量:

代码语言:javascript
复制
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

按索引功能关闭选项卡:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2018-09-11 15:57:26

还不清楚为什么您认为您必须摆脱路由使用选项卡导航。选项卡导航和路由不是不兼容的。若要在路由中使用MatTabNavBar和MatTabLink,请设置应用程序路由,以便每个“选项卡”都是路由,将路由器选项添加到mat选项卡链接元素中,并使用路由器出口托管选项卡内容。这应该比您计划的要简单得多,因为您不需要担心动态选项卡内容的“创建”和后退按钮的使用。

下面是一个基本示例中的选定代码,完整的演示是在StackBlitz上完成的

模板

代码语言:javascript
复制
<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>

组件

代码语言:javascript
复制
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 {}

App模块

代码语言:javascript
复制
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 { }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52278819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档