с использованием пользовательских данных; всегда надо подписываться? - PullRequest
0 голосов
/ 07 августа 2020

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

Через несколько лет после Angular мне нужно вернуться к этому на некоторое время. project.

В проекте очень минимальный user.service.ts с вызовом только серверной части для получения текущих пользовательских данных. Система используется внутри компании и доступна только в сети компании, поэтому аутентификация на сервере выполняется через некоторый прокси / заголовок magi c. Интерфейс просто должен вызвать бэкэнд, и вернется нужный пользовательский объект. Нам не разрешено хранить данные локально на машинах (localStorage et c.)

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

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

  public user: Observable<User>;
  private userSubject: BehaviorSubject<User>;

  constructor(private http: HttpClient) {

    this.userSubject = new BehaviorSubject<User>({} as User);
    this.user = this.userSubject.asObservable();

    this.setUser();
  }

  public get userValue(): User {
    return this.userSubject.value;
  }

Моя цель - использовать это как одноэлементный сервис (вводимый с помощью providedIn; 'root'), метод setUser вызывает бэкэнд.

  setUser(): void {
    this.http.get<User>('url').subscribe((user: User) => {
      this.userSubject.next(user);
    });
  }

Мой последний шаг - один раз получить значение объекта пользователя, обновленное в конструкторе app.component, подписавшись на него

    this.userService.user.subscribe({
      next: (user: User) => {
        this.user = user;
      }
    });

Мое видение: все остальные компоненты могут просто вызывать геттер

    this.currentUser = this.userService.userValue;

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

// welcome.component.ts
  currentUser: User;

  constructor(
    private userService: UserService
  ) {
    this.currentUser = this.userService.userValue;
    console.log(this.userService.userValue);
    setTimeout(() => {
      console.log(this.userService.userValue);
    }, 5000);
    this.userService.user.subscribe({
      next: (user: User) => {
        console.log(user);
      }
    });
  }

// LOG EMPTY User{}, User{...} (after 5sec) User{...}

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

То есть, я получаю лог c за этим. Вызов бэкэнда асинхронный, там значение обновляется после того, как я его использую. Я подумал, что использую его в неправильном варианте использования, но ... какой вариант использования будет правильным?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...