首页 文章

Angular 5将服务注入组件

提问于
浏览
0

我的身份验证服务组件存在问题,因为每次加载auth组件时,服务似乎都会重新初始化 . 我应用程序中应该出现的流程是,应用程序启动时,根应用程序组件应发送一个登录请求,以检查当前会话是否经过身份验证 . 此登录请求正在从身份验证服务发送 . auth-service有一个主题广播一个布尔值,指示用户是否经过身份验证,具体取决于登录/注销操作的结果 .

除了一个场景之外,这很有用 . 如果我在auth页面上启动应用程序,导航离开组件并返回到它,我无法从服务获得正确的身份验证状态(true / false) . 打印时的字段(在服务中)由于某种原因未定义 . 为了调试,我甚至在ngOnInit函数中插入了console.logs,以查看是否有任何组件/服务正在重新初始化,但没有 .

以下是它现在看起来的代码示例, app.component.ts (根组件):

constructor(private requestService: RequestService,
              private authService: AuthService) {}

  ngOnInit() {
    console.log("App component init");
    this.requestService.get('http://localhost:8000/api/csrf/')
      .subscribe(
        success => {
          this.authService.login('', '');
        }
    );
  }

由于第一次CSRF检查,登录请求被触发,到目前为止效果很好 .

auth.service.ts

@Injectable()
export class AuthService implements OnInit, OnDestroy {
  authenticated: boolean;
  authSubject: Subject<boolean>;

  constructor(private requestService: RequestService) {
    console.log("Auth service constructor");
    this.authSubject = new Subject<boolean>();
  }

  ngOnInit() {
    console.log("Auth service init");
    this.authSubject.subscribe(
      next => {
        this.authenticated = next;
      }
    );
  }

  login(username: string, password: string) {
    console.log("Auth service login");
    this.requestService.post(LOGIN_URL, { username: username, password: password })
      .subscribe(
        next => {
          this.authSubject.next(true);
          console.log("[AuthService] Success logging in.");
        },
        error => {
          console.log("[AuthService] Error logging in.");
        },
        () => {
          console.log("[AuthService] Auth service completed.");
        }
      );
  }

  logout() {
    this.requestService.post(LOGOUT_URL, {})
    .subscribe(
      next => {
        this.authSubject.next(false);
        console.log('[AuthService] Success logging out.');
      },
      error => {
        console.log("[AuthService] Error logging out.");
      },
      () => {
        console.log("[AuthService] Auth service completed.");
      });
  }

  isAuthenticated(): boolean {
    return this.authenticated;
  }

  ngOnDestroy() {
    console.log("Auth service destroyed");
    this.authSubject.unsubscribe();
  }
}

在上面我们可以看到,我已经在构造函数中而不是在ngOnInit中实例化了Subject . 这是因为当从 app.component.ts 触发登录时,尚未创建导致崩溃的主题 . 这仍然有效 .

auth.component.ts

export class AuthComponent implements OnInit {
  authenticated: boolean;

  constructor(private authService: AuthService) { }

  ngOnInit() {
    console.log("Auth component init");
    this.authService.authSubject.subscribe(
      next => {
        this.authenticated = next;
      }
    );
    this.authenticated = this.authService.isAuthenticated();
    console.log(this.authenticated);
  }

  onLogin(form: NgForm) {
    const username = form.value.username;
    const password = form.value.password;
    this.authService.login(username, password);
  }

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

所以,这就是我被困的地方 . 当我登录时,看到我成功获得响应并且authenticated = true . 但是,当我离开auth视图然后返回到它时,从authService.isAuthenticated获取经过身份验证的值会让我返回“undefined”!服务在那里并且完好无损(我点击了ngOnDestroy服务,没有任何东西被解雇)所以我猜测有一个参考问题或者什么,我只是在文档中找不到任何东西来帮助我 .

请指教 .

2 回答

  • 0

    尝试使用 BehaviorSubject 而不仅仅是 Subject . BehaviorSubject 将在订阅之前广播最后一个值加上任何新值,而主题只会在您订阅后广播出任何新数据 .

    What is the difference between Subject and BehaviorSubject?

  • 0

    问题在于没有为角度服务调用ngOnInit,因此在auth服务中从未激活订阅 . 当我将订阅移动到服务构造函数时,一切正常!

相关问题