#angular #guard #angular-canload
Вопрос:
UPD. Решенный. Я использовал 2 экземпляра службы, и это вызвало проблемы
Я застрял с охраной canLoad. Когда я нажимаю кнопку в компоненте, я хочу изменить значение false в службе и позволить своему охраннику загрузить модуль. Но охранник получает только ложное значение. Как я могу заставить его работать и видеть, когда я обновляю значение в службе? Похоже, он не видит, когда значение изменяется, и срабатывает до того, как я его обновлю
Вот мой телохранитель
import { Injectable } from '@angular/core';
import { CanLoad } from '@angular/router';
import { AuthenticationService } from '../services/auth.service';
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanLoad {
constructor(private authService: AuthenticationService) {}
canLoad(): boolean {
if (this.authService.isLogged()) {
return true;
} else {
return false;
}
}
}
Мой автосервис
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
private isUserLoggedIn = new BehaviorSubject(false);
isLogged() {
console.log(this.isUserLoggedIn.value); // <--- FALSE
return this.isUserLoggedIn.value;
}
login() {
this.isUserLoggedIn.next(true);
console.log(this.isUserLoggedIn.value); // <--- TRUE
}
}
Маршрутизация:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from './guards/auth.guard';
const routes: Routes = [
{
path: '',
pathMatch: 'full',
redirectTo: 'login'
},
{
path: 'dashboard',
loadChildren: () => import('./modules/dashboard/dashboard.module').then(m => m.DashboardModule),
canLoad: [AuthGuard]
},
{
path: 'login',
loadChildren: () => import('./modules/login/login.module').then(m => m.LoginModule)
},
{
path: '**',
redirectTo: 'dashboard'
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Main Module
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AuthGuard } from './guards/auth.guard';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
],
providers: [AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }
Login Module
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginComponent } from './login.component';
import { NzFormModule } from 'ng-zorro-antd/form';
import { LoginRoutingModule } from './login-routing.module';
import { NzInputModule } from 'ng-zorro-antd/input';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { AuthenticationService } from 'src/app/services/auth.service';
@NgModule({
declarations: [
LoginComponent
],
imports: [
CommonModule,
NzFormModule,
LoginRoutingModule,
NzInputModule,
NzButtonModule
],
providers: [
AuthenticationService
]
})
export class LoginModule { }
Модуль маршрутизации входа в систему
import { RouterModule, Routes } from '@angular/router';
import { NgModule } from '@angular/core';
import { LoginComponent } from './login.component';
const routes: Routes = [
{
path: '',
pathMatch: 'full',
component: LoginComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LoginRoutingModule {}
Кнопка
<button (click)="submitForm()">pressme</button>
submitForm() {
this.authService.login();
this.router.navigate(['dashboard']);
}
Комментарии:
1. пожалуйста, поделитесь также своим маршрутом
2. сделано, может быть, с ним что-то не так?
3. и ваш основной файл модуля, а также
4. я также добавил все модули и кнопки
5. попробуйте добавить
AuthGuard
в массив поставщиковLoginModule
и посмотрите
Ответ №1:
Значение canLoad()
будет получено только при первом предварительном доступе к компоненту. Как только login()
это будет сделано, попробуйте перейти к компоненту/странице, которые вы хотите загрузить, и это должно сработать.
Кроме того, может помочь удаление частного в вашем объекте поведения?
Комментарии:
1. я делаю это в компоненте : submitForm() { this.AuthService. войти(); this.router.navigate([‘панель мониторинга’]); } но ничего не работает. Охранник видит только ложное значение
2. Может быть, сделайте свою ценность не частной
3. ничего не изменилось. все равно охранник видит ложную ценность. метод login() изменяет его, и я вижу это, но guard получает первое значение, которое было помещено в BehaviorSubject(ложь)
4. Вы следуете шаблону: 1-я маршрутизация возвращает ложь — > вы нажимаете кнопку входа в систему — > > получите истину в службе — > > > снова перейдите к маршруту без перезагрузки вашей страницы, что нарушит ваше состояние?
5. да, но охрана не видит изменений
Ответ №2:
Может быть, использование observable поможет:
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
private isUserLoggedIn = new BehaviorSubject(false);
public isUserLoggedIn$: Observable<boolean>
constructor(){
this.isUserLoggedIn$ = this.isUserLoggedIn.asObservable();
}
login() {
this.isUserLoggedIn.next(true);
}
}
@Injectable()
export class AuthGuard implements CanLoad {
constructor(private authService: AuthenticationService) {}
canLoad(route: Route,segments: UrlSegment[]): boolean|UrlTree|Observable<boolean|UrlTree>|Promise<boolean|UrlTree> {
return this.authService.isUserLoggedIn$;
}
}