angular - 基于 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');
}
}
解决方案
注销还应该将您重定向到另一个视图并销毁有关会话的所有内容。对于重定向,您可以在构造函数中导入路由器并调用它:
constructor(private router: Router){}
logout() {
this.storage.remove('ACCESS_TOKEN');
this.authenticationState.next(false);
this.router.navigate(["some-page"]);
}
推荐阅读
- python - Python current.futures 多次导入库(在顶级范围内多次执行代码)
- matlab - 使用matlab对声音进行反卷积
- java - hibernate get me 引起:java.lang.AbstractMethodError
- c++ - 使用 std::vector 是否安全
作为异构记录的存储? - firebase - 文档中的 Firestore 更新数组字段
- scala - 选择以特定模式开头的字段:Spark XML Parsing
- python - 将 dash_html_components 传递给 Jinja 模板
- colors - 如何添加png文件
- neo4j - 获取指定起始节点下所有节点的最快方法
- reactjs - 根据路径中的参数渲染组件