Задержки с angular универсальными проверками и проверками ngIf - Angular 9 - PullRequest
0 голосов
/ 18 марта 2020

Я только начинаю интегрировать angular универсальный в уже существующее приложение, и я замечаю, что на секунду страница отображается с неправильным макетом, и когда страница полностью загружается, все выглядит нормально.

Это пример:

Я получаю статус входа при загрузке страницы следующим образом:

this.authService.isLoggedIn.subscribe(res => {
  this.isLoggedIn = res;
});

И устанавливаю другой макет в зависимости от результата, если true или false:

<div *ngIf="isLoggedIn" class="user-logged">
    // user logged in
</div>
<div *ngIf="!isLoggedIn" class="user-logged">
    // user not logged in
</div>

Но когда служба возвращает true (что означает, что пользователь вошел в систему), на секунду я вижу состояние не вошедшего в систему, затем страница загружается, и все выглядит нормально. Это также происходит со всеми проверками BreakpointObserver.

ОБНОВЛЕНИЕ 1: Это то, что я пробовал: я создал AppConfigService:

@Injectable()
export class AppConfigService {

  private isLoggedStatus: boolean;

  constructor(private authService: AuthService) { }

  public isLoggedIn(): boolean {
    return this.isLoggedStatus;
  }

  load() {
    return new Promise((resolve, reject) => {
      this.authService.isLoggedIn.subscribe(loggedInStatus => {
        this.isLoggedStatus = loggedInStatus;
        resolve(true);
      });
    });
  }

}

В моем AuthService :

private isLoginSubject = new BehaviorSubject<boolean>(this.isAuthenticated);

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

get isAuthenticated(): boolean {
    const token = this.getToken();
    if (token) {
      if (jwtHelper.isTokenExpired(token)) {
        return false;
      } else {
        return true;
      }
    } else {
      return false;
    }
}

В моем app.module.ts

export function appConfigFactory(provider: AppConfigService) {
  return () => provider.load();
}

providers: [
    AppConfigService,
    {
        provide: APP_INITIALIZER,
        useFactory: appConfigFactory,
        deps: [AppConfigService],
        multi: true
    }
]

Я думаю, что проблема заключается в использовании локального хранилища на стороне сервера, но если это проблема, как я могу проверить если пользователь залогинен?

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Это происходит потому, что вы используете localStorage. Серверная версия вашего приложения не может получить доступ к локальному хранилищу (например, не может получить доступ к window, navigator на любом объекте браузера), поэтому считает пользователя неподключенным.

При работе с angular универсальный и аутентификационный, вы можете использовать куки, к которым сервер может получить доступ.

Есть несколько доступных библиотек, но из того, что я видел, они не полностью готовы к использованию с angular 9:

1 голос
/ 18 марта 2020

Это происходит потому, что когда ваше приложение впервые оценивает isLoggedIn, оно ложно (или не определено, это зависит от того, как вы его определили).

Затем, когда событие подписки возвращает данные, * Значение 1004 * изменяется, поэтому ваш html изменяется также из-за вашего состояния *ngIf.

Если вы хотите загрузить данные isLoggedIn до рендеринга приложения, вы можете использовать APP_INITIALIZER.

Этот пост объясняет, как его использовать: https://www.cidean.com/blog/2019/initialize-data-before-angular-app-starts/

Этот старше, но тоже хорош: https://devblog.dymel.pl/2017/10/17/angular-preload/

РЕДАКТИРОВАТЬ

В вашем AppConfigService, isLoggedStatus должно быть Наблюдаемым, или оно будет неопределенным (и будет оцениваться как ложное) до разрешения Обещания.

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

Примеры шагов:

  • Отображение страницы входа в систему.
  • Когда пользователь нажимает имя входа , позвоните на сервер и дождитесь ответа.
  • ЕСЛИ успешно:
    • isLoggedStatus = true
    • сохранить сеанс (в LocalStorage, если хотите)
    • отобразить ваш компонент (и isLoggedIn будет true)
  • ЕСЛИ сбой:
    • isLoggedStatus = false
    • отобразить ваш компонент (и isLoggedIn будет false)
    • пользователь должен иметь возможность повторить попытку входа
...