Я знаю, что было несколько вопросов по этому поводу, но ни один из тех, что я нашел, действительно не ответил на вопрос, который у меня в голове.
Через несколько лет после 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 за этим. Вызов бэкэнда асинхронный, там значение обновляется после того, как я его использую. Я подумал, что использую его в неправильном варианте использования, но ... какой вариант использования будет правильным?