为什么在AuthGuard中值未更改为false?

时间:2018-10-15 13:20:30

标签: javascript html angular typescript angular6

在模板组件AppComponent中,根据值,变量this.loggedInService.isLoggedInlogIn()logout()方法之间切换,这在应用程序组件{{1}中} AppComponent被服务subscribe中的这些方法所取代,并根据方法将变量的值更改为LoggedinServicetrue

同样在Guard的方法false中,我根据变量checkLogin (url: string)的值返回truefalse

启动应用程序时,我无法进入模块,单击按钮可以,但是,如果重复单击按钮“退出”,则仍然可以进入模块。

strong>

如何使切换到this.loggedInService.isLoggedIn的工作正常,以便身份验证正常进行,并保存重新启动页面时在输入和输出之间切换状态的值?

** AppComponent.html:**

checkLogin

** AppComponent.ts **

导出类AppComponent实现OnInit {     讯息:字串;

        <li class="nav-item">
            <a class="btn btn-outline-success"
               [class.btn-outline-success]="!this.loggedInService.isLoggedIn$"
               [class.btn-outline-danger]="this.loggedInService.isLoggedIn$"
               (click)="this.loggedInService.isLoggedIn$ ? logout() : logIn()">
                {{this.loggedInService.isLoggedIn$ ? 'Exit' : 'Enter'}}
            </a>
        </li>

}

LoggedinService:

constructor(public loggedInService: LoggedinService,
            public router: Router) {
    this.setMessage();
}

ngOnInit() {}

logIn(): void {
    this.loggedInService.login().subscribe(() => {
        if (this.loggedInService.isLoggedIn$) {
            let redirect = this.loggedInService.redirectUrl ? this.loggedInService.redirectUrl :
                '/gallery';
            this.router.navigate([redirect]);
        }
    });
}

logout(): void {
    this.loggedInService.logout();
}

AuthGuard:

export class LoggedinService {
isLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
isLoggedIn$: Observable<boolean> = this.isLoggedIn.asObservable();
  redirectUrl: string;

  constructor() {}

  login(): Observable < boolean > {
    return of(true).pipe(
      delay(100),
      tap(val => this.isLoggedIn.next(true))
    );
  }

  logout(): void {
    this.isLoggedIn.next(false);
  }
}

1 个答案:

答案 0 :(得分:1)

isLoggedIn中的

LoggedinService是原始数据类型。因此它不通过引用传递。它通过价值传递。因此,如果某处发生更改,则相同的更改将不会在使用该更改的其他位置反映出来。

此行为仅在对象通过引用和非值传递时表现出来。

您可以使用BehaviorSubject来解决此问题。

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { Router } from '@angular/router';

import { delay, tap } from 'rxjs/operators';

@Injectable()
export class LoggedinService {

  isLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
  isLoggedIn$: Observable<boolean> = this.isLoggedIn.asObservable();
  redirectUrl: string;

  constructor(private router: Router) { }

  login(): Observable<boolean> {
    this.isLoggedIn.next(true);
    return this.isLoggedIn$;
  }

  logout(): Observable<boolean> {
    this.isLoggedIn.next(false);
    return this.isLoggedIn$;
  }

}

现在,您将获得isLoggedIn类型的booleanisLoggedIn$类型的Observable,而不是subscribe类型的.subscribe获取用户的登录状态。

您必须在AppComponent中this.loggedInService.login()this.loggedInService.login()isLoggedIn$,因为它们都返回isLoggedIn。您必须创建一个本地.subscribe属性,并将其返回给isLoggedIn中返回的值。然后,您可以基于此Observable<boolean>属性,基于模板设置按钮文本并单击处理程序。

对于AuthGuard,由于后卫可以返回Promise<boolean>booleanreturn this.loggedInService.isLoggedIn$,因此您可以简单地select * from dbo.InstallationErrorLog where data = 'Input string was not in a correct format.' and ErrorDate > GETDATE()-90 and Function ='ProcessTblFromCSV'

这是您推荐的Sample StackBlitz