Угловая асинхронная труба не обновляется, когда наблюдаемая изменена - PullRequest
0 голосов
/ 28 мая 2019

У меня есть приложение Angular.

  • В приложении init мы должны показать перенаправляющий счетчик (пользователь не авторизован)
  • Когда пользователь вошел в систему, тогда мы должны показать содержимое

Я сделал это, как показано ниже: HTML:

<div *ngIf="(isLoggedIn$ | async); else loading">
    <!-- some other content -->
    <router-outlet></router-outlet>
</div>

<ng-template #loading>
    <app-spinner text="Redirecting..."></app-spinner>
</ng-template>

TS:

isLoggedIn$: Observable<boolean>;

constructor(private authService: AuthService) {}

ngOnInit() {
    this.isLoggedIn$ = this.authService.isLoggedIn();
}

Хорошо работает в приложении init. Когда пользователь вошел в систему, я все еще вижу счетчик перенаправления. Я должен обновить окно, чтобы увидеть содержимое розетки маршрутизатора.

Мой временный обходной путь - поместить <router-outlet> внутрь <ng-template #loading>, например:

<ng-template #loading>
    <app-spinner text="Redirecting..."></app-spinner>
    <router-outlet></router-outlet> <!-- HERE workaround -->
</ng-template>

Но я не хочу использовать этот обходной путь навсегда, поскольку я хочу исправить эту проблему Observable - как я уже говорил, она не обновляется, даже когда console.log () сообщает, что я вошел в систему.

Вот мой сервис аутентификации:

@Injectable({
    providedIn: 'root'
})
export class AuthService {

  manager: UserManager = new UserManager(environment.settings);

  constructor() {
  }

  getUser(): Observable<User> {
    return from(this.manager.getUser());
  }

  isLoggedIn(): Observable<boolean> {
    return this.getUser()
      .pipe(
        map(user => {
          return user != null && !user.expired;
        })
      );
  }

  startAuthentication(): Promise<void> {
    return this.manager.signinRedirect();
  }

  completeAuthentication(): Observable<User> {
    return from(this.manager.signinRedirectCallback());
  }

  async signOut() {
    await this.manager.signoutRedirect();
  }
}

Конечно, я также использую CanActivate.

1 Ответ

0 голосов
/ 28 мая 2019

Мое решение состоит в том, чтобы добавить emitCompleted метод к AuthService и вызвать его из AuthCallback компонента.

AuthService:

private isLoggedInState = new BehaviorSubject<boolean>(false);

isLoggedIn(): Observable<boolean> {
    return this.isLoggedInState.asObservable();
}

emitCompleted(user: User) {
    this.isLoggedInState.next(user != null && !user.expired);
}

Компонент AuthCallback:

export class AuthCallbackComponent implements OnInit {

  constructor(
    private authService: AuthService,
    private router: Router
    ) { }

  ngOnInit() {
    this.authService.completeAuthentication()
      .subscribe((result => {
        this.authService.emitCompleted(result);
      })
    );
  }
}
...