我在Angular中有一个名为NewEventComponent
的组件,它只包含一个用于提交新事件的表单。在它的提交方法上它有这个代码:
onSubmit() {
this.isSendingRequest = true;
this.geolocationService.geocodeAddress(this.location.value).subscribe(
(results: google.maps.GeocoderResult[]) => {
if (results && results.length) {
const eventData: EventData = {
name: this.name.value,
location: [results[0].geometry.location.lat(), results[0].geometry.location.lng()],
startDate: this.datetimeService.convertDateAndTimeToISOString(this.startDate.value, this.startTime.value),
endingDate: this.datetimeService.convertDateAndTimeToISOString(this.endingDate.value, this.endingTime.value),
description: this.description.value,
sport: this.sport.value,
intensity: this.intensity.value,
fee: this.fee.value,
maxPlayers: this.maxPlayers.value
};
this.eventService.createEvent(eventData).subscribe(
(res: any) => {
this.alertService.createAlert({ message: EVENT_CREATED_MESSAGE, type: AlertType.Success });
this.router.navigate(['events', res.data.event.id]);
}
);
} else {
this.handleInvalidLocationError();
}
}
);
}
它只将事件发送到服务器并重定向到事件页面,即EventDetails
组件。此组件仅向服务器请求所请求的事件,并将其作为输入传递给子组件。这是代码:
TS:
@Component({
selector: 'app-event-details',
templateUrl: './event-details.component.html',
styleUrls: ['./event-details.component.scss']
})
export class EventDetailsComponent implements OnInit {
private event: EventResponse;
constructor(
private activatedRoute: ActivatedRoute,
private eventService: EventService
) { }
ngOnInit() {
this.getEvent();
}
getEvent(): void {
this.activatedRoute.params.subscribe(
(params: Params) => {
this.eventService.getEvent(params.id).subscribe(
(res: any) => {
this.event = res.data.event;
}
);
}
);
}
}
HTML:
<div class="row">
<div class="col">
<div class="info-wrapper">
<app-event-details-info [event]="event">
</app-event-details-info>
</div>
</div>
</div>
子组件EventDetailsInfo
仅接收事件作为此@Input() event: EventResponse;
之类的输入,并在html中显示如下信息:<h5>{{ event?.name }}</h5>
。
这里的问题是,当从NewEvent
组件导航到EventDetails
组件时,不会触发更改检测,因此在我单击DOM中的任何位置之前,更改不会显示。但是当我直接通过网址导航到EventDetails
组件时,页面才能正常呈现。
我在更改检测方面缺少什么?任何的想法?谢谢!
PS:EventService
仅执行HTTP调用并将其作为Observables返回,如:
createEvent(eventData: EventData): Observable<any> {
return this.http.post(`${environment.apiUrl}/events/`, eventData);
}
getEvent(eventId: string): Observable<any> {
return this.http.get(`${environment.apiUrl}/events/${eventId}`);
}
PS2:这是'onSubmit()'方法中使用的GeolocationService
方法:
geocodeAddress(address: string): Observable<google.maps.GeocoderResult[]> {
const response: Subject<google.maps.GeocoderResult[]>
= new Subject<google.maps.GeocoderResult[]>();
const request: google.maps.GeocoderRequest = { address };
this.geocoder.geocode(request,
(results: google.maps.GeocoderResult[]) => {
response.next(results);
}
);
return response;
}
答案 0 :(得分:1)
<强>更新强>
onSubmit() {
this.isSendingRequest = true;
this.geolocationService.geocodeAddress(this.location.value).subscribe(
(results: google.maps.GeocoderResult[]) => {
this.zone.run(() => π
if (results && results.length) {
const eventData: EventData = {
name: this.name.value,
location: [results[0].geometry.location.lat(), results[0].geometry.location.lng()],
startDate: this.datetimeService.convertDateAndTimeToISOString(this.startDate.value, this.startTime.value),
endingDate: this.datetimeService.convertDateAndTimeToISOString(this.endingDate.value, this.endingTime.value),
description: this.description.value,
sport: this.sport.value,
intensity: this.intensity.value,
fee: this.fee.value,
maxPlayers: this.maxPlayers.value
};
this.eventService.createEvent(eventData).subscribe(
(res: any) => {
this.alertService.createAlert({ message: EVENT_CREATED_MESSAGE, type: AlertType.Success });
this.router.navigate(['events', res.data.event.id]);
}
);
} else {
this.handleInvalidLocationError();
}
}
});
);
}
<强>原始强>
也许事件是在Angular区域之外发出的。
尝试:
constructor(private zone: NgZone) { }
和
this.zone.run(() => this.router.navigate(['events', res.data.event.id]));
如果这样可以解决问题,您应该修复EventService
答案 1 :(得分:1)
根据订阅发生的顺序,您可能完全错过了该事件。考虑使用shareReplay(1)
并公开事件。
或者,将事件的订阅移动到构造函数:
constructor(
private activatedRoute: ActivatedRoute,
private eventService: EventService
) {
this.getEvent();
}
ngOnInit() {
}