我正在尝试根据从宁静的服务(当前返回日期列表)收到的响应来填充日历。
我正在从组件的ngInit()方法中调用restful服务方法。
ngOnInit() {
this.refreshCalendar();
for (var calendarEntryShortvar of this.calendarEntriesShort) {
console.log("cal entry short from ngInit: " + calendarEntryShortvar.start);
}
}
由于内容长度不确定,上述循环打印内容失败。
这是this.refreshCalendar();的代码。
refreshCalendar(){
this.calendarService.retrieveAllCalendarEntriesShort('test')
.subscribe (
response => {
console.log("printing response")
console.log(response)
this.calendarEntriesShort = response;
for (var calendarEntryShortvar of this.calendarEntriesShort) {
console.log("cal entry short: " + calendarEntryShortvar.start);
this.calendarEntry = new CalendarEntry(calendarEntryShortvar.start, calendarEntryShortvar.start,
'title event 1', this.colors.redx, this.actions);
console.log("pushing calendar entry")
this.events.push(this.calendarEntry);
}
}
)
}
上面的代码成功打印了数组的内容,这意味着它在收到服务的响应后正在执行。
以下是服务呼叫的代码:
retrieveAllCalendarEntriesShort(用户名){
console.log("retrieveAllCalendarEntries");
return this.http.get<CalendarEntryShort[]>(`${CALENDER_API_URL}/users/${username}/calendarentries`);
}
不用说,在填充日历日期数组之前,将呈现日历的HTML。这是HTML组件:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<angular-calendar-year-view [events]="events" [viewDate]="viewDate" [customTemplate]="Customtemplate" ></angular-calendar-year-view>
<ng-template #Customtemplate>
My custom templatex
</ng-template>
<angular-calendar-year-view
[themecolor]="themecolor"
[events]="events"
[viewDate]="viewDate"
[nothingToshowText]="nothingToshowText"
(eventClicked)="eventClicked($event)"
(actionClicked)="actionClicked($event)" >
</angular-calendar-year-view>
以某种方式,我需要让Angular暂停直到收到响应。这仅仅是使其成为同步呼叫的问题吗?我不确定为什么这行不通。
答案 0 :(得分:1)
在Angular中有几种处理异步调用的方法。我的第一个选择通常是尽可能使用异步管道(因此无需担心取消订阅)。这样的事情应该适合您:
更新您的api服务调用,以在可观察对象上进行映射,并为其添加变量:
calendarResults$: Observable<CalendarEntry[]>;
refreshCalendar() {
this.calendarResults$ = this.calendarService.retrieveAllCalendarEntriesShort('test')
.pipe(map((response: any[]) => {
return response.map(calendarEntryShortvar => {
return new CalendarEntry(calendarEntryShortvar.start, calendarEntryShortvar.start, 'title event 1', this.colors.redx, this.actions)
});
}));
}
然后,您可以在* ngIf模板中使用异步管道(可以显示一些加载动画):
<ng-container *ngIf="calendarResults$ | async as calendarResults; else loading"
<angular-calendar-year-view [events]="calendarResults" [viewDate]="viewDate" [customTemplate]="Customtemplate" ></angular-calendar-year-view>
// your other code dependent on this async data
</ng-container>
<ng-template #loading>
Loading...
</ng-template
答案 1 :(得分:0)
您必须等待响应后再进行处理。另外,您可以等待它,然后再将处理它的html部分添加到视图中。
将api调用放入服务中,这是最好的做法:
为您服务
// service.ts
refreshCalendar() {
return this.calendarService.retrieveAllCalendarEntriesShort('test');
}
在您的组件中:
events: any = [];
constructor(private service: Service) {}
ngOnInit() {
this.service.refreshCalendar()
.subscribe(response => {
this.calendarEntriesShort = response;
for (var calendarEntryShortvar of this.calendarEntriesShort) {
console.log("cal entry short from ngInit: " + calendarEntryShortvar.start);
for (var calendarEntryShortvar of this.calendarEntriesShort) {
this.calendarEntry = new CalendarEntry(calendarEntryShortvar.start,
calendarEntryShortvar.start,
'title event 1', this.colors.redx, this.actions);
this.events.push(this.calendarEntry);
}
}
});
}
您认为
<div *ngIf="events.length > 0">
<angular-calendar-year-view [events]="events" [viewDate]="viewDate"
[customTemplate]="Customtemplate" >
</angular-calendar-year-view>
<ng-template #Customtemplate>
My custom templatex
</ng-template>
<angular-calendar-year-view
[themecolor]="themecolor"
[events]="events"
[viewDate]="viewDate"
[nothingToshowText]="nothingToshowText"
(eventClicked)="eventClicked($event)"
(actionClicked)="actionClicked($event)" >
</angular-calendar-year-view>
</div>