首页 > 解决方案 > 基于 UserRole 的应用程序选项卡指令问题

问题描述

我创建了一个指令来根据用户角色在我的应用程序中显示或隐藏选项卡。注销后,该指令不会更新视图并且选项卡不会消失。

有我的has-role.directive.ts文件:

import { Directive, Input, TemplateRef, ViewContainerRef, OnInit } from '@angular/core';
import { AuthService } from 'src/app/auth/auth.service';
import { Storage } from '@ionic/storage';

@Directive({
    selector: '[appHasRole]'
})
export class HasRoleDirective implements OnInit {
    @Input() appHasRole: Array<string>;
    isVisible = false;

    constructor(
        private authService: AuthService,
        private templateRef: TemplateRef<any>,
        private viewContainer: ViewContainerRef,
        private storage: Storage
    ) {}

    ngOnInit() {
        this.storage.get('ACCESS_TOKEN').then(token => {
            if (token) {
                this.authService.getUserRoles().subscribe((data: any) => {
                    if (!data.roles) {
                        this.viewContainer.clear();
                    }
                    if (data.roles.some(r => this.appHasRole.includes(r))) {
                        if (!this.isVisible) {
                            this.isVisible = true;
                            this.viewContainer.createEmbeddedView(this.templateRef);
                        } else {
                            this.isVisible = false;
                            this.viewContainer.clear();
                        }
                    }
                });
            }
        });
    }
}

选项卡的定义如下:

<ion-tabs>

  <ion-tab-bar slot="bottom">
    <ion-tab-button tab="home">
      <ion-icon name="paper"></ion-icon>
      <ion-label>{{'TABS.tab_1' | translate}}</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="dictionary" (click)="goToDictionary()">
      <ion-icon name="book"></ion-icon>
      <ion-label>{{'TABS.tab_2' | translate}}</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="profile" (click)="goToProfile()">
      <ion-icon name="person"></ion-icon>
      <ion-label>{{'TABS.tab_3' | translate}}</ion-label>
    </ion-tab-button>

    <ion-tab-button *appHasRole="['moderator']" tab="admin" (click)="goToAdmin()">
      <ion-icon name="construct"></ion-icon>
      <ion-label>Moderator</ion-label>
    </ion-tab-button>
  </ion-tab-bar>

</ion-tabs>

相同的错误也有 FAB 按钮,但一旦我得到指令当前问题的解决方案,我将能够修复它。

在此处输入图像描述

这是我的AuthService

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { tap } from 'rxjs/operators';
import { Observable, BehaviorSubject } from 'rxjs';

import { Storage } from '@ionic/storage';
import { API_ENDPOINTS } from 'src/environments/environment';
import { Platform } from '@ionic/angular';

@Injectable({
    providedIn: 'root'
})
export class AuthService {
    public authenticationState = new BehaviorSubject(false);

    constructor(
        private httpClient: HttpClient,
        private storage: Storage,
        private platform: Platform
    ) {
        this.platform.ready().then(() => {
            this.checkAuthToken();
        });
    }

    private checkAuthToken() {
        this.storage.get('ACCESS_TOKEN').then(res => {
            if (res) {
                this.authenticationState.next(true);
            } else {
                this.storage.remove('ACCESS_TOKEN');
            }
        });
    }

    login(user): Observable<any> {
        return this.httpClient
            .post(`${API_ENDPOINTS.API_V1}auth/token/login/`, user)
            .pipe(
                tap(async res => {
                    if (res.auth_token) {
                        await this.storage.set('ACCESS_TOKEN', res.auth_token);
                        this.authenticationState.next(true);
                    }
                })
            );
    }

    getUserRoles() {
        return this.httpClient.get(`${API_ENDPOINTS.API_V1}get-user-roles/`);
    }

    getAuthorizationToken() {
        return this.storage.get('ACCESS_TOKEN');
    }

    logout() {
        this.storage.remove('ACCESS_TOKEN');
        this.authenticationState.next(false);
    }

    isLoggedIn() {
        return this.authenticationState.value;
    }
}

有个人资料页面弹出组件。Popover 中的 Logout Button 是在此处定义的:

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

import { PopoverController } from '@ionic/angular';
import { AuthService } from 'src/app/auth/auth.service';
import { Router } from '@angular/router';
import { Storage } from '@ionic/storage';

@Component({
    template: `
        <ion-list>
            <ion-item button href="https://m.chechen-dictionary.com/" target="_blank">
                <ion-icon slot="start" name="globe"></ion-icon>
                <ion-label>Chechen Dictionary</ion-label>
            </ion-item>
            <ion-item button (click)="openTutorial()">
                <ion-icon slot="start" name="help-circle-outline"></ion-icon>
                <ion-label>{{ 'PROFILE.tutorial' | translate }}</ion-label>
            </ion-item>
            <ion-item button (click)="logout()">
                <ion-icon slot="start" name="log-out"></ion-icon>
                <ion-label>{{ 'PROFILE.logout' | translate }}</ion-label>
            </ion-item>
        </ion-list>
    `
})
export class ProfileSettingsPage {
    constructor(
        public popoverCtrl: PopoverController,
        private authService: AuthService,
        private router: Router,
        private storage: Storage
    ) {}

    logout() {
        this.authService.logout();
        this.popoverCtrl.dismiss();
        this.router.navigateByUrl('/tabs/home');
    }
}

标签: angularionic-frameworkionic4

解决方案


注销还应该将您重定向到另一个视图并销毁有关会话的所有内容。对于重定向,您可以在构造函数中导入路由器并调用它:

constructor(private router: Router){}


logout() {
    this.storage.remove('ACCESS_TOKEN');
    this.authenticationState.next(false);
    this.router.navigate(["some-page"]);
}

推荐阅读