Как долго служба Angular2 содержит значения переменных класса

У меня есть приложение Angular2 с dataservice, которое должно отображать различное содержимое на основе текущего пользователя, вошедшего в систему. Моя проблема заключается в том, что моя служба проверки подлинности не хранит значение данных после его первого создания, что делает меня неспособным получить доступ к идентификатору пользователя в моих других поставщиках данных.

Вот то, что я сделал в настоящее время, чтобы выполнить это с 2 службами, 1 компонентом и 1 authguard (см. ниже). Логика, которую я ожидал бы:

  1. Authguard вызывается перед активацией маршрута inbox
  2. Authguard вызывает службу AuthService, которая подписывается на FirebaseAuth, и задает переменную authState
  3. Если пользователь вошел в систему, DataService должен иметь значение authService.id от AuthService

Однако то, что происходит, что authService.id выдает «не установлен», так как кажется, что он никогда не будет установлен, даже если пользователь вошел в систему. Это может быть доказано путем добавления console.log(state)после подписки на auth$ в AuthService, который в настоящее время печатает текущего зарегистрированного пользователя.

Поэтому мой вопрос заключается в том, как долго переменная private authState хранится в AuthService? Существует ли какое-либо другое решение для получения наблюдаемого значения authService.переменная id перед выполнением других вызовов в my DataService? Одно из решений, которое я могу придумать, будет использовать switchmap в DataService для каждого вызова данных, но это кажется неоптимальным.

AuthService

@Injectable()
export class AuthService {

  private authState: FirebaseAuthState = null;

  constructor(private af: AngularFire, public auth$: FirebaseAuth) {
    auth$.subscribe((state: FirebaseAuthState) => {
      this.authState = state;
    });
  }

  get authenticated() {
    return this.authState !== null;
  }

  get id(): string {
    return this.authenticated ? this.authState.uid : 'Not set';
  }
}

AuthGuard

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(): Observable<boolean> {
    return this.authService.auth$
      .take(1)
      .map(authState => !!authState)
      .do(authenticated => {
        if (!authenticated) {
          this.router.navigate(['/compose']);
        }
      });
  }

}

служба данных

@Injectable()
export class EmailService {

  private emails: FirebaseListObservable<IEmail[]>;
  private emailUserPath: string;

  constructor(private af: AngularFire, authService: AuthService) {
    this.emailUserPath = `/emails/${authService.id}`;
  }

  getAllEmails(): FirebaseListObservable<IEmail[]> {
    return this.af.database.list(this.emailUserPath);
  }
}

Модуль маршрута

const routes: Routes = [
  { path: 'inbox',  component: InboxComponent, canActivate: [AuthGuard] }
];

@NgModule({
  imports: [ RouterModule.forChild(routes) ],
  providers: [AuthGuard],
  exports: [ RouterModule ]
})

export class EmailRoutingModule {}

Модуль Приложения

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { EmailsModule } from './emails/emails.module';

import { AppRoutingModule }     from './app-routing.module';
import { AngularFireModule, AuthProviders, AuthMethods } from 'angularfire2';
import { UserSearchComponent } from './shared/user-search/user-search.component';
import {AuthService} from "./auth/auth.service";
import {AuthGuard} from "./auth/auth-guard";
import {EmailRoutingModule} from "./emails/email-routing.module";
import { UserOrLoginComponent } from './navigation/user-or-login/user-or-login.component';
import { NavigationListComponent } from './navigation/navigation-list/navigation-list.component';

export const firebaseConfig = {
  apiKey: "hidden",
  authDomain: "hidden",
  databaseURL: "hidden",
  storageBucket: "hidden"
};

const myFirebaseAuthConfig = {
  provider: AuthProviders.Google,
  method: AuthMethods.Popup
};

@NgModule({
  declarations: [
    AppComponent,
    UserSearchComponent,
    UserOrLoginComponent,
    NavigationListComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule,
    EmailRoutingModule,
    AngularFireModule.initializeApp(firebaseConfig, myFirebaseAuthConfig),
    EmailsModule // I include the Emails module below here
  ],
  providers: [
    AuthService,
    AuthGuard
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Модуль Приложения Электронной Почты

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ComposeComponent } from './compose/compose.component';
import { EmailDetailComponent } from './email-detail/email-detail.component';
import { InboxComponent } from './inbox/inbox.component';
import { ReplyComponent } from './reply/reply.component';
import { ReplyListComponent } from './reply/reply-list/reply-list.component';
import { EmailService } from './shared/email.service';

import { FormsModule } from '@angular/forms';
import {ReplyService} from "./reply/reply.service";

@NgModule({
  imports: [
    CommonModule,
    FormsModule
  ],
  declarations: [
    ComposeComponent,
    EmailDetailComponent,
    InboxComponent,
    ReplyComponent,
    ReplyListComponent
  ],
  providers: [
    EmailService,
    ReplyService
  ]
})

export class EmailsModule { }

export { EmailService };

1 ответ

  1. Они хранят свои ценности, пока живут. Когда вы переходите к чему-то вне модуля, который задает значение для службы, вы теряете значение. Поскольку у вас больше нет доступа к экземпляру, который имеет значение set.

    Услуги являются одноэлементными для каждого поставщика. Это означает, что если вам нужен сервис/значение глобально, вам нужно сделать его одноэлементным на глобальном уровне. Предоставление AuthServiceat AppModuleдолжно решить вашу проблему.

    import { AuthService } from 'path/to/service'
    
    @NgModule({
      imports: [ ],
      providers: [AuthService], //<-- provided globally
      exports: [ ]
    })
    
    export class AppModule {}