ionic3和angular 5中的动态标签渲染

时间:2018-04-25 16:56:14

标签: ionic3 angular5

我想渲染动态标签,但我无法做到这一点。第一次选项卡渲染效果很好,但是当我们更改refreshTabs函数参数时,其标签会显示第一次渲染标签。假设第一次加载APP_TEACHER_TABS元素,当它变为ADMIN时,它的渲染APP_TEACHER_TABSAPP_ADMIN_TABS两者都有,但我想只渲染APP_ADMIN_TABS

根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
    });
  }
}

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

1 个答案:

答案 0 :(得分:4)

我不完全知道如何设置系统,但I put together a 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>

我将所有标签放在一个数组中,并提供了一个可以访问每个标签的角色列表。

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 }
];

然后,当用户更改时,我处理了标签,以根据用户所拥有的角色确定用户可以访问的标签:

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)});
    });
}

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

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));
        }
    }
}

这应该是根据登录用户动态更改标签的最终结果。