提问者:小点点

Angular 5将服务注入组件


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

这非常有效,除了一种情况。如果我在身份验证页面上启动应用程序,远离组件并返回到它,我无法从服务中获得正确的身份验证状态(真/假)。打印时的字段(在服务中)由于某种原因处于未定义状态。为了调试,我甚至在ngOnInit函数中插入了sole. logs,以查看是否有任何组件/服务被重新初始化,但什么都没有。

这是它现在的样子的代码示例,app.组件. 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中实例化主题。这是因为当从app.组件. 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();
  }

所以,这就是我卡住的地方。当我登录时,看到我成功地得到了一个响应,并且身份验证=true。但是,当我远离身份验证视图,然后回到它时,从autService. isAuthenticated获取身份验证值会给我返回“未定义”!服务在那里并且完好无损(我利用了服务的ngOnDestroy,那里没有触发任何内容),所以我猜是引用问题或其他什么,我只是在留档中找不到任何帮助我的东西。

请指教。


共2个答案

匿名用户

尝试使用行为主体而不仅仅是主体行为主体将广播订阅前的最后一个值加上任何新值,而主体只会广播订阅后的任何新数据。

主体和行为主体有什么区别?

匿名用户

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