Извините, это будет долго.
У меня есть страница входа в систему, которая после успешного входа в систему передает объект поведения пользователя с токеном пользователя, а затем перенаправляет на страницу повестки дня.
На этой странице перечислены некоторые события, и, если я нажму на карточку события, я перенаправлюсь на детали события. Эти две страницы обрабатываются одним и тем же сервисом. Этот сервис зависит от UserService. На первой странице (листинг) я могу взять BehaviorSubject UserService, но при переходе к деталям он устанавливается равным нулю.
Вот мои страницы и сервисы (при необходимости усекаются):
user.service.ts
@Injectable({
providedIn: 'root'
})
export class UserService {
private baseUrl = 'http://frat/';
private userSource = new BehaviorSubject<User>(null);
public user$ = this.userSource.asObservable();
constructor(private httpClient: HttpClient) { }
login(user: User): Observable<HttpResponse<User>> {
return this.httpClient
.post(`${this.baseUrl}/login`, user, {
observe: 'response'
})
.pipe(
tap(async (response: HttpResponse<User>) => {
// this.setUser(new User(response.body)); // = new User(response.body);
})
);
}
public buildAuthorizationHeader(): string {
return 'Basic ' + btoa(this.userSource.getValue().pseudo + ':' + this.userSource.getValue().password);
}
/**
* Met à jour l'observable pour avertir les observateurs dans les composants.
* @param user
*/
setUser(value) {
this.userSource.next(value);
}
}
evenements.service.ts
@Injectable({
providedIn: 'root'
})
export class EvenementsService {
private baseUrl = 'http://frats/evenements';
private user: User;
private evenementsSource = new BehaviorSubject<Evenement[]>([]);
private evenementSource = new BehaviorSubject<Evenement>(null);
public evenements$ = this.evenementsSource.asObservable();
public evenement$ = this.evenementSource.asObservable();
constructor(private httpClient: HttpClient, private userService: UserService) {
this.userService.user$.subscribe(user => {
console.log('EvtSvc User : ', user);
this.user = user;
});
}
public getEvenements(): Observable<Evenement[]> {
return this.httpClient
.get<Evenement[]>(this.baseUrl, {
headers: {
Authorization: this.userService.buildAuthorizationHeader()
}
})
.map((evts) => {
return evts.map((e) => new Evenement(e));
});
}
public getEvenementById(id): Observable<Evenement> {
return this.httpClient
.get<Evenement>(this.baseUrl + '/' + id, {
headers: {
Authorization: this.userService.buildAuthorizationHeader()
}
})
.map((evt) => new Evenement(evt));
}
public setEvenements(value) {
this.evenementsSource.next(value);
}
public setEvenement(value) {
this.evenementSource.next(value);
}
}
повестка дня.ts (в котором перечислены события, работает нормально)
@Component({
selector: 'app-agenda',
templateUrl: './agenda.page.html',
styleUrls: ['./agenda.page.scss'],
})
export class AgendaPage implements OnInit {
private evenements: Evenement[] = [];
public titre = 'Agenda';
constructor(private evenementService: EvenementsService) {}
ngOnInit() {
this.evenementService.evenements$.subscribe(evenements => this.evenements = evenements);
}
ionViewDidEnter() {
this.loadData();
}
loadData(event = null) {
this.evenementService.getEvenements().subscribe(evenements => {
this.evenementService.setEvenements(evenements);
});
if (isNull(event) === false) {
event.target.complete();
}
}
}
evenement.page.ts (в котором пользователь userService имеет значение null, отображаемое после щелчка по отображаемому событию в повестке дня)
@Component({
selector: 'app-evenement',
templateUrl: './evenement.page.html',
styleUrls: ['./evenement.page.scss'],
})
export class EvenementPage implements OnInit {
@ViewChild('map', {read: false, static: false}) mapContainer: ElementRef;
map: any;
private id: number;
private evenement: Evenement;
private localisation: Localisation;
public titre = 'Evénement';
constructor(
public route: ActivatedRoute,
private cal: Calendar,
private evenementService: EvenementsService,
private launchNavigator: LaunchNavigator,
private locSvc: LocalisationService,
private userService: UserService
) { }
ngOnInit() {
this.id = parseInt(this.route.snapshot.paramMap.get('id'), 10);
this.evenementService.evenement$.subscribe((evenement) => this.evenement = evenement);
}
ionViewDidEnter() {
this.loadData();
}
loadData(): void {
this.evenementService.getEvenementById(this.id).subscribe(evenement => {
this.evenementService.setEvenement(evenement);
});
}
... other methods to make map and marker appear ...
}
login.page.ts
@Component({
selector: 'app-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {
private loginForm: FormGroup;
public titre = 'Connexion';
constructor(private userService: UserService, public alertController: AlertController, private router: Router) {}
ngOnInit() {
this.loginForm = new FormGroup({
login: new FormControl('', Validators.required),
password: new FormControl('', Validators.required)
});
this.userService.user$.subscribe((user) => {
console.log('Login user : ', user);
});
}
login(form) {
this.userService.login(form.value).subscribe((response) => {
if (response.status === 200) {
this.userService.setUser(new User(response.body));
this.router.navigateByUrl('agenda');
}
},
(error) => {
let message;
if (error.status === 401) {
message = 'Vos identifiants n\'ont pas été reconnus.';
} else {
message = 'Une erreur a eu lieu, veuillez retenter plus tard.';
}
this.presentAlert(message);
});
}
async presentAlert(message) {
const alert = await this.alertController.create({
header: 'Erreur',
subHeader: 'Un problème a eu lieu',
message,
buttons: ['OK']
});
await alert.present();
}
}
Я не могу понять, почему userService похож на сброс. Может быть, при входе на evenement.page.ts создается другой экземпляр, но почему тогда?
Спасибо за помощь.