ionic3 和 Angular 5 中的动态选项卡渲染

Utp*_*aul 3 ionic3 angular5

我想渲染动态选项卡,但我无法执行此操作。首次选项卡渲染良好,但当我们更改refreshTabs函数参数时,其选项卡会显示首次渲染选项卡。假设第一次加载APP_TEACHER_TABS元素,当它改变时,ADMIN它会渲染APP_TEACHER_TABSAPP_ADMIN_TABS但我只想渲染APP_ADMIN_TABS

根选项卡.ts

import {Component} from '@angular/core';
import {IonicPage, NavController, NavParams, PopoverController} from 'ionic-angular';
import {TabInterface} from "../../models/tabsModels";
import {AuthProvider} from "../../providers/auth";
import {APP_ADMIN_TABS, APP_STUDENT_TABS, APP_TEACHER_TABS} from "../../constants";
import {SwitchAccountService} from "../../providers/switch-account";

@IonicPage({
  name: 'page-root-tabs',
  priority: 'high'
})

@Component({
  selector: 'page-root-tabs',
  templateUrl: 'root-tabs.html',
})
export class RootTabsPage{

  tabs =[];
  userLabel: any;

  constructor(public navCtrl: NavController,
              public navParams: NavParams,
              private auth:AuthProvider,
              public popoverCtrl: PopoverController,
              private switchAccountService: SwitchAccountService) {

    this.initializeTabs();

  }

  initializeTabs(){

    this.switchAccountService
      .getUserLabel()
      .subscribe(message =>{
        this.userLabel = message;
        this.refreshTabs(this.userLabel);
      });
  }

  refreshTabs(item){

      if( item == 'ADMIN'){
        while(this.tabs.length){
          this.tabs.pop();
        }

        APP_ADMIN_TABS.forEach(el => {
          this.tabs.push(<TabInterface>{label: el.label, icon: el.icon, component: el.component});
        });

        // this.tabs.splice(this.tabs.indexOf(0), 1);
        // setTimeout(()=>{
        //   APP_ADMIN_TABS.forEach(el => {
        //     this.tabs.push(<TabInterface>{label: el.label, icon: el.icon, component: el.component});
        //   });
        // },4000);


        //this.tabs.splice(0,1);
      }

      else if(item == 'TEACHER'){

        APP_TEACHER_TABS.forEach(el => {
          this.tabs.push(<TabInterface>{label: el.label, icon: el.icon, component: el.component});
        });

      }

      else{

        if(this.auth.currentUser.user_flag == 2){

          APP_TEACHER_TABS.forEach(el => {
            this.tabs.push(<TabInterface>{label: el.label, icon: el.icon, component: el.component});
          });

        }else{

          APP_STUDENT_TABS.forEach(el => {
            this.tabs.push(<TabInterface>{label: el.label, icon: el.icon, component: el.component});
          });

        }
      }

  }

  presentPopover(myEvent) {
    let popover = this.popoverCtrl.create('page-popover');
    popover.present({
      ev: myEvent
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

根选项卡.html

<ion-header>
  <ion-navbar no-border-bottom color="customColor">

    <ion-title class="custom-font" style="font-size: 2.1em;" text-center>
      DASHBOARD
    </ion-title>

    <ion-buttons end>
      <button ion-button icon-only (click)="presentPopover($event)">
        <ion-icon name="md-more"></ion-icon>
      </button>
    </ion-buttons>

  </ion-navbar>
</ion-header>

<ion-tabs tabsPlacement="top">
  <ion-tab *ngFor="let tab of tabs"
           [tabIcon]="tab.icon"
           [tabTitle]="tab.label"
           [root]="tab.component">
  </ion-tab>
</ion-tabs>
Run Code Online (Sandbox Code Playgroud)

Dan*_*pel 5

我不完全知道你的系统是如何设置的,但我整理了一个 stackblitz,展示了如何让选项卡随着用户的变化而动态变化。

正如您所发现的,如果您更改了 Ionic 中呈现的实际选项卡,它就无法真正正常工作。您可以做的是使用该[show]属性动态显示/隐藏它们。

<ion-tabs #ionTabs>
  <ion-tab *ngFor="let tab of tabs$ | async; trackBy: trackByFn"
           [tabIcon]="tab.icon"
           [tabTitle]="tab.label"
           [root]="tab.component"
           [show]="tab.show">
  </ion-tab>
</ion-tabs>
Run Code Online (Sandbox Code Playgroud)

我将所有选项卡放在一个数组中,并给出了可以访问每个选项卡的角色列表。

export const TABS: TabInterface[] = [
  { label: 'Home', icon: 'home', component: HomePage, roles: [UserRole.Admin], show: false },
  { label: 'About', icon: 'information-circle', component: AboutPage, roles: [UserRole.Admin, UserRole.Teacher], show: false },
  { label: 'Contact', icon: 'contacts', component: ContactPage, roles: [UserRole.Teacher, UserRole.Student], show: false }
];
Run Code Online (Sandbox Code Playgroud)

然后,随着用户的更改,我处理选项卡,以确定用户可以根据他们所拥有的角色访问哪些选项卡:

tabs$ = this.userService.user$
    .takeUntil(this.destroy$.asObservable())
    .map(user => this.processTabsForUser(user))
    .do(tabs => this.selectCorrectTab(tabs));

...

private processTabsForUser(user: User): TabInterface[] {
    return TABS.map(tab => {
        return Object.assign({}, tab, { show: user && user.isAuthorized(tab.roles)});
    });
}
Run Code Online (Sandbox Code Playgroud)

为了在用户在另一个用户登录时发生更改时正常工作(这在真实的系统中不应该发生,我不认为但是......)我必须处理当前选择的选项卡并确保用户有权访问它。如果没有,我将选择用户有权访问的第一个选项卡:

private selectCorrectTab(tabs: TabInterface[]) {
    const selectedTab = this.ionTabs.getSelected();
    const tab = tabs.find(t => selectedTab && t.component === selectedTab.root);

    if (!tab || !tab.show) {
        const index = tabs.findIndex(t => t.show);

        if (!!~index) {
            // bug in Ionic causes the need to do in setTimeout if user changes when already logged in
            setTimeout(() => this.ionTabs.select(index));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该会得到根据登录用户动态更改选项卡的最终结果。