对不起,这会很长。
我有一个登录页面,成功登录后,该页面会向UserService的BehaviorSubject提供用户的令牌,然后重定向到议程页面。
此页面列出了一些事件,如果我单击事件的卡片,则会重定向到该事件的详细信息。这两个页面由同一服务处理。此服务取决于UserService。 在第一页(列表)中,我可以获取UserService的BehaviorSubject,但是就像我在查看详细信息时将其设置为null。
这是我的页面和服务(如有必要,将其截断):
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);
}
}
agenda.page.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像reset。也许在evenment.page.ts上输入时创建了另一个实例,但是为什么要这样呢?
感谢您的帮助。
答案 0 :(得分:0)
好吧,这很棘手。
在议程(列表)页面上,我使用带有href属性的离子卡。当我点击时,将呈现详细信息,但UserService会重置。
<ion-card button="true" href="'evenements/' + e.id" color="light" *ngFor="let e of evenements">
我用一个名为click。的事件替换了href属性,该事件调用router.navigateByUrl(event / id),它可以解决问题!
<ion-card button="true" (onclick)="showEvent(e.id)" color="light" *ngFor="let e of evenements">
showEvent(id) {
this.router.navigateByUrl('evenement/' + id);
}
如果有人有解释,我不明白为什么会这样。
至少有效!