Data binding between html element property and script value is out of sync

Description of the problem:
There is an availability calendar that shows whether a person is busy in a particular slot (every day is divided into two slots). This state is stored in the isSlotFreeboolean 2d array (this array is 31 x 2 in size). Initially, all values ​​in this array are initialized to true. Then the request for http is executed by the server with a request for busy dates. After receiving them, a function is called setIsSlotFree()to set the corresponding values ​​in the array to false. The view (HTML file) has an element <td>for each slot. Each of these elements updates its color (using class styles) based on the logical value stored in the corresponding index of the array. The problem is thatThe html page does not reflect the changes made to the array after the function call setIsSlotFree(). (i.e., the html elements still see all the values ​​as true). However, when I print the array in the console immediately after the get request, it changes the corresponding values ​​to false. When an event is fired, only the view is updated to the correct values. What is the problem?

Below are the relevant parts of the component.ts file

export class CalendarComponent implements OnInit {

  viewDate: Date;
  isSlotFree: boolean[][] = [
    [true, true]
  ];

  constructor(private http: HttpClient) {

  }


  ngOnInit() {
    this.viewDate = new Date();
    var i: number;
    var j: number;

    for (i = 1; i < 31; i++) {
      this.isSlotFree.push([true, true]);
    }
    let p = new HttpParams().set('month', (this.viewDate.getMonth() + 1).toString());

    this.http.get < busyDateResponse[] > ("http://localhost:51967/api/stylists/getBusyDates", {
      params: p
    }).subscribe(res => {
      this.setIsSlotFree(res);
    });

    this.x = true;
    console.log(this.isSlotFree);
    this.viewDate = new Date();

  }

  setIsSlotFree(res: busyDateResponse[]): void {
    var busy_date: busyDateResponse;
    for (busy_date of res) {
      var temp: number = (busy_date.slot == 'm') ? 0 : 1;
      this.isSlotFree[busy_date.day - 1][temp] = false;
    }

  }
}

interface busyDateResponse {
  $id: string;
  day: number;
  month: number;
  year: number;
  slot: string;
}
Run codeHide result

The corresponding parts of the component.html file are shown below.

<ng-template #cellTemplate let-day="day" let-locale="locale">
  <div class="cal-cell-top">
    <div class="cal-day-number w3-xlarge">{{ day.date | calendarDate:'monthViewDayNumber':locale }}</div>
    <br>

  </div>
  <div *ngIf="day.inMonth && day.isFuture">
    <table style="width:100%">

      <tr>
        <td class="calendar-slot" [ngClass]="{'w3-green': isSlotFree[day.date.getDate()-1][0], 'w3-red': !isSlotFree[day.date.getDate()-1][0]}">{{isSlotFree[day.date.getDate()-1][0]}}Morning</td>
        <mat-checkbox (change)="editSelectedSlots($event)" [checked]="isSelectedSlot(day.date.getDate() + '_' + day.date.getMonth() + '_' + day.date.getFullYear() + '_m')?true:false" [id]="day.date.getDate() + '_' + day.date.getMonth() + '_' + day.date.getFullYear() + '_m'"
          *ngIf="isSlotFree[day.date.getDate()-1][0]"></mat-checkbox>
      </tr>
      <tr>
        <td class="calendar-slot" [ngClass]="{'w3-green': isSlotFree[day.date.getDate()-1][1], 'w3-red': !isSlotFree[day.date.getDate()-1][1]}">{{isSlotFree[day.date.getDate()-1][1]}}Evening</td>
        <mat-checkbox (change)="editSelectedSlots($event)" [checked]="isSelectedSlot(day.date.getDate() + '_' + day.date.getMonth() + '_' + day.date.getFullYear() + '_e')?true:false" [id]="day.date.getDate() + '_' + day.date.getMonth() + '_' + day.date.getFullYear() + '_e'"
          *ngIf="isSlotFree[day.date.getDate()-1][1]">
        </mat-checkbox>
      </tr>
    </table>
  </div>

</ng-template>

<div>
  <mwl-calendar-month-view [viewDate]="viewDate" [events]="events" (eventClicked)="eventClicked($event)" (dayClicked)="dayClicked($event)" [cellTemplate]="cellTemplate" [refresh]="refresh">
  </mwl-calendar-month-view>
  <div class="w3-center">
    <button mat-raised-button>Make booking</button>
  </div>
</div>
Run codeHide result

Notice what <mwl-calendar-month-view>uses ng-templateto generate cells in the calendar.

+4
source share
1 answer

, angular. setIsSlotFree(). , , . , . , ChangeDetectorRef.detectChanges() setIsSlotFree().

constructor(private http: HttpClient, private ref: ChangeDetectorRef), isSlotFree() :

setIsSlotFree(res:busyDateResponse[]):void {
    var busy_date:busyDateResponse;
    for(busy_date of res) {
        var temp:number = (busy_date.slot=='m')?0:1;
        this.isSlotFree[busy_date.day-1][temp] = false;
    }
    this.ref.detectChanges();        
  }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
Hide result
+1

Source: https://habr.com/ru/post/1691101/


All Articles