Angular - правильно получает ответ и заполняет резервный массив, но HTML-компонент Angular видит только нулевой массив - PullRequest
1 голос
/ 20 июня 2019

Я пытаюсь заполнить календарь, основываясь на ответе, который я получаю от успокоительного сервиса (в настоящее время возвращает список дат).

Я вызываю метод службы restful из метода ngInit () компонента.

 ngOnInit() {
    this.refreshCalendar(); 

    for (var calendarEntryShortvar of this.calendarEntriesShort) {
      console.log("cal entry short from ngInit: " + calendarEntryShortvar.start);
    }

  }

Приведенный выше цикл для печати содержимого не выполняется из-за неопределенной длины.

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

Ответы [ 2 ]

1 голос
/ 21 июня 2019

Существует несколько способов обработки асинхронных вызовов в 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)
        });
      }));
}

Затем вы можете использовать асинхронный каналв * ngЕсли ваш шаблон (с возможностью отображения анимации загрузки):

<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
0 голосов
/ 21 июня 2019

Вы должны дождаться ответа, прежде чем иметь дело с ним. Кроме того, вы можете подождать, прежде чем добавить 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...