刷新页面时隐藏角度材质<mat-toolbar>



我正在开发一个Angular Material应用程序。

我在myapp.component.html:中有这个垫子工具栏

<mat-toolbar color="primary" *ngIf="isLoggedIn$ | async" fullscreen>
<button mat-icon-button (click)="sidenav.toggle()"><mat-icon>menu</mat-icon></button>
<h1>SAP</h1>
</mat-toolbar>
<mat-sidenav-container [style.marginTop.px]="mobileQuery.matches ? 56 : 0">
<mat-sidenav #sidenav [mode]="mobileQuery.matches ? 'over' : 'side'"
[fixedInViewport]="mobileQuery.matches">
<mat-nav-list>

<a mat-list-item *ngIf="isOp==false" (click)="sidenav.toggle()" routerLink="/trafos">
<mat-icon svgIcon="fohama"></mat-icon> <span class="nav-caption">&nbsp;  Transformadores</span>
</a>
<a mat-list-item *ngIf="isOp==false" (click)="sidenav.toggle()" routerLink="/empleados">
<mat-icon>assignment_ind</mat-icon> <span class="nav-caption">&nbsp;  Empleados</span>   
</a>
<a mat-list-item *ngIf="isOp==false" (click)="sidenav.toggle()" routerLink="/clientes">
<mat-icon>assignment_ind</mat-icon> <span class="nav-caption">&nbsp;  Clientes</span>   
</a>
<a mat-list-item *ngIf="isOp==false" (click)="sidenav.toggle()" routerLink="/procesos">
<mat-icon>settings</mat-icon> <span class="nav-caption">&nbsp;  Procesos</span>   
</a>
<a mat-list-item *ngIf="isOp==false" (click)="sidenav.toggle()" routerLink="/modificarProcesos">
<mat-icon>edit</mat-icon> <span class="nav-caption">&nbsp;  Modificar Procesos</span>   
</a>
<a mat-list-item *ngIf="isOp==false" (click)="sidenav.toggle()" routerLink="/order">
<mat-icon>low_priority</mat-icon> <span class="nav-caption">&nbsp;  Priorizar Transformadores</span>   
</a>
<a mat-list-item *ngIf="isOp==false" (click)="sidenav.toggle()" routerLink="/referencias">
<mat-icon>add_comment</mat-icon> <span class="nav-caption">&nbsp;  Referencias</span>   
</a>
<a mat-list-item *ngIf="isOp==false" (click)="sidenav.toggle()" routerLink="/reportes">
<mat-icon>insert_chart_outlined</mat-icon> <span class="nav-caption">&nbsp;  Reportes</span>   
</a>
<a mat-list-item (click)="sidenav.toggle()" (click)="logout()">
<mat-icon>exit_to_app</mat-icon><span class="nav-caption">&nbsp;  logout</span>
</a>

</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>

<router-outlet></router-outlet>    
</mat-sidenav-content>
</mat-sidenav-container>

一切都很好。这个栏在应用程序组件中,ngOnInit((有这个:


this.isLoggedIn$ = this.authService.isLoggedIn;
}

我遇到的问题是当用户重新加载页面时。导航栏消失。修复它的最佳解决方案是什么?当用户登录时,系统会在localStorage中保存一个令牌。我想使用它,但我不知道如何确定ngIf中的条件,因为我在其中有异步管道。

提前感谢

更新这是我的授权。服务:

export class AuthService {
apiUrl = `${environment.baseUrl}/auth`;
message:string;
durationInSeconds:1;
isOp:boolean=true;
sector:number=0;
private loggedIn = new BehaviorSubject<boolean>(false);
userChange$ = new BehaviorSubject({isOp: null, sector: null});
get isLoggedIn() {
return this.loggedIn.asObservable(); 
}

constructor(private http:HttpClient,private _snackBar: MatSnackBar,private router:Router) { }
login(data: any): Observable<any> {
return this.http.post<any>(`${this.apiUrl}/login`, data)
.pipe(
tap(_ => 
{
//console.log(_);
this.openSnackBar("Sesión iniciada");
this.loggedIn.next(true);
this.userChange(_.isOp,_.sector);
this.isOp=_.isOp;
this.sector=_.sector;
//localStorage.setItem("sector",_.sector);
//localStorage.setItem("isOp",_.isOp);
}
),
catchError(this.handleError('login Failed', ))
);
}
userChange(isOp, sector){
this.userChange$.next({
isOp: isOp,
sector: sector
});
}
isLogged(){
if(localStorage.getItem('sector'))
{
this.loggedIn.next(true);

}

}
logout(){
this.router.navigate(['/login']);
localStorage.clear();
this.loggedIn.next(false);
}
}

这是我的应用程序组件。ts:

export class AppComponent implements OnInit {
title = 'client';
isOp:boolean;
sector:number;
isLoggedIn$: Observable<boolean>;
// isLogged$:Observable<boolean>;
//usDetail:Observable<Object>;
mobileQuery: MediaQueryList;
private _mobileQueryListener: () => void;
constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher,private router: Router,private matIconRegistry: MatIconRegistry,sanitizer: DomSanitizer,private authService:AuthService,private mensajesService:MensajesService) {
this.mobileQuery = media.matchMedia('(max-width: 600px)');
this._mobileQueryListener = () => changeDetectorRef.detectChanges();
this.mobileQuery.addListener(this._mobileQueryListener);
this.matIconRegistry.addSvgIcon(
'fohama',
sanitizer.bypassSecurityTrustResourceUrl('assets/logofohamaico.svg')
);
}

ngOnInit() {
// this.isLogged=localStorage.getItem('token');
//console.log(this.isLogged);
// this.isLogged$ = this.tokenInterceptor.isLogged;
this.isLoggedIn$ = this.authService.isLoggedIn;
console.log("")
this.mensajesService.getMessage().subscribe(res=>{
console.log("Respuesta: ",res);
this.isOp=res.isOp;
})
ngOnDestroy(): void {
this.mobileQuery.removeListener(this._mobileQueryListener);
}

logout() {
this.authService.logout();
}

更新2这是我的应用程序例程模块.ts

const routes: Routes = [
{path:'login',component:LoginComponent,data:{title:'Login'}},
{path:'register',component:RegisterComponent,data:{title:'Registro'}},
{path:'',component:LoginComponent},
{path:'reportes',component:DailyReportComponent,canActivate:[GuardianGuard]},
{path: 'empleados', component:EmpleadosComponent,canActivate:[GuardianGuard]},
{path: 'clientes',component:ClientesComponent,canActivate:[GuardianGuard] },
{path:'procesos',component:TimerReloadedComponent,canActivate:[GuardianGuard]},
{path:'modificarProcesos',component:ModificarProcesosComponent,canActivate:[GuardianGuard]},
{path:'order',component:OrderComponent,canActivate:[GuardianGuard]},
{path:'referencias',component:ReferenciasComponent,canActivate:[GuardianGuard]},
{path:'trafos',component:TransformadoresReloadedComponent,canActivate:[GuardianGuard]}
//{path:'**',redirectTo:'/login'}
];

登录组件:

export class LoginComponent implements OnInit {
loginForm: FormGroup;
nombreUs = '';
pass = '';
matcher = new ErrorStateMatcher();
isLoadingResults = false;  
messageSnack:string;
durationInSeconds=3;
private us = new BehaviorSubject<Object>("");
get usDetail() {
return this.us.asObservable(); 
}
constructor(private formBuilder: FormBuilder, private router: Router, private authService: AuthService,private _snackBar: MatSnackBar, private mensajeService:MensajesService) { }
ngOnInit() {
this.loginForm = this.formBuilder.group({
'nombreUs' : [null, Validators.required],
'pass' : [null, Validators.required]
});
}
onFormSubmit(form: NgForm) {
this.authService.login(form)
.subscribe(res => {
//console.log(res);
if(res){
this.mensajeService.enviarMensaje({
isOp:res.isOp,
sector:res.sector
})
this.us.next({isOp:res.isOp,sector:res.sector});
if (res.token) {
localStorage.setItem('token', res.token);
}
if(res.isOp==true)
{
this.router.navigate(['procesos']);
}
else{
this.router.navigate(['trafos']);
}
}
else{
this.openSnackBar("Usuario o contraseña inválidos");
}
}, (err) => {

// this.openSnackBar("Usuario o contraseña inválidos");
console.log(err);
});
}
openSnackBar(mensaje) {
this._snackBar.open(mensaje,"mensaje", {
duration: this.durationInSeconds * 1000,
});
}
login(){
this.router.navigate(['transformadores'])
}
register() {
this.router.navigate(['register']);
}
}
//Managing form validation
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const isSubmitted = form && form.submitted;
return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
}
}

所以,因为这个工具栏在app.component中;主页";是登录组件(调用auth.Service(,在用户重新加载页面之前,一切都很好

如果需要存储用户的状态,应该使用本地存储。因为每次用户重新加载页面时,一切都是从头开始重建的。

在组件中

this.isLoggedIn = this.authService.isAuthenticated();

在您的身份验证服务中

import { StorageService } from './storage.service';
@Injectable({
providedIn: 'root',
})
export class AuthService {
isLoggedIn$ = new BehaviorSubject(false);
constructor(private localStorage: StorageService) {
this.isLoggedIn$.next(this.checkSessionStorage());
}
public login(...) {
// make the request
this.storageService.setToken(a_Token);
this.isLoggedIn$.next(true);
}
public logout() {
this.storageService.clearToken();
this.isLoggedIn$.next(false);
}
public checkSessionStorage(): boolean {
return this.localStorage.getToken() !== null;
}
public isAuthenticated(): Obseravable<boolean> {
return this.isLoggedIn$.asObservable();
}
}

在您的存储服务中

import { Injectable } from '@angular/core';
import { LocalStorageService } from 'ngx-webstorage';
const TOKEN = 'token';
@Injectable({
providedIn: 'root',
})
export class StorageService {
constructor(private localStorageService: LocalStorageService) { }
getToken(): string {
return this.localStorageService.retrieve(TOKEN);
}
setToken(token: string): void {
this.localStorageService.store(TOKEN, token);
}
clearToken() {
this.localStorageService.clear(TOKEN);
}
}

当用户登录和注销时,您需要分别设置和清除令牌。

当然,这只是一个基本的用例。您不必每次都调用存储,您可能希望将其作为可观察对象。用户第一次加载应用程序时,它会调用存储,将其保存在内存中,并在用户没有刷新应用程序时重用它。

我希望它能有用:(

由于粘贴的代码非常少。。。到目前为止,我只能给出一些我能想到的建议:

  • 像前面提到的其他人一样,你应该检查

    this.authService.isLoggedIn
    

    总是返回一个oberservable。

  • 关于如何确定ngIf:中的条件

    *ngIf="isLoggedIn$| async as isLoggedIn"
    

    您可以在中打印出isLoggedIn的值

this.authService.isLoggedIn是否返回true的可观测值?

我怀疑不是。尝试将isLoggedIn$配置为behaviorSubject,并在ngOnInit上调用this.authService.isLoggedIn.next(this.authServices.isLoggerIn(

isLoggedIn$ = new BehaviorSubject(false);
ngOninit() {
this.isLoggedIn$.next(this.authService.isLoggedIn);
}

另一个解决方案是不使用|async,而在HTML文件中使用:

*ngIf=authService.isLoggedIn

最新更新