Search code examples
angularng2-bootstrap

Quirk with ng2-bootstrap modal in Angular2 rc5


I've been working on building a calendar app using Angular2 and I recently upgraded to rc5. My calendar allows users to create/edit appointment details through use of a detail modal, then displays changes and prompts a user to confirm the changes in another modal. It also allows the user to drag and drop the events and calculates the new date/time accordingly. The app was working fine before upgrading to rc5. Since the upgrade, when a user drags an event to a new time the confirm modal opens and shows the last change, and only when the user clicks inside the modal does it update to reflect the new changes.

Expected flow: drag/drop -> update values -> open display to show new changes

Current flow: drag/drop -> open display -> (Upon clicking in modal) change values to reflect new event time

I haven't changed my code, so I'm suspecting there's some change to the way rc5 is handling the modal. I'm using "ng2-bootstrap", and the flow of the detail edit still works as normal.

viewProviders: [BS_VIEW_PROVIDERS] directives: [MODAL_DIRECTIVES]

Drag and Drop Handler:

confirmEvent(response) {
    this.changeEvent = this.calendarService.getEvent(this.events, response.existingEvent);
    this.event = response.newEvent;
    this.confirmAction = response.action;
    this.eventService.getEventParticipants(this.changeEvent);
    this.appointmentConfirmComponent.show();
  }

Detail response handler:

handleDetailsResponse(response) {
    this.changeEvent = this.calendarService.getEvent(this.events, response.event);
    this.eventService.getEventParticipants(this.changeEvent);
    this.event = response.event;
    this.appointmentDetailComponent.hide();

    switch (response.action) {
      case 'delete':
        if(this.changeEvent.id && this.changeEvent.id !== '') {
          this.confirmAction = 'delete';
          this.appointmentConfirmComponent.show();
        }
        break;
      case 'save':
        if (this.event.id && this.event.id !== '') {
          this.confirmAction = 'update';
        } else {
          this.confirmAction = 'save';
        }
        this.appointmentConfirmComponent.show();
        break;
      default:
        this.confirmAction = 'ERROR';
        this.updateSources();
        break;
    }
  }

If need be I can force an event on the modal to trick it into updating, but that seems sloppy. Is there a clean way to force the modal to update?

calendar.component.html

<div class="row" style="margin-top: 1rem;">
    <div class="card col-xs-8 col-xs-offset-1 flex" style="padding-top: 1rem;">
        <calendar-body class="flex-content"
                [calendarEvents]='events' 
                (editEvent)='editEvent($event)' (confirmEvent)='confirmEvent($event)'>
        </calendar-body>
    </div>

    <appointment-detail [event]="event" (submitDetails)="handleDetailsResponse($event)"></appointment-detail>
    <appointment-confirm [existingEvent]="changeEvent" [newEvent]="event" [action]="confirmAction" (submitConfirmation)="handleConfirmResponse($event)"></appointment-confirm>
</div>

Solution

  • My solution to fix the issue was to pull in the ChangeDetectorRef into the parent component and call this.cd.detectChanges() once the event fires on the drag and drop. This causes the virtual DOM to realize that the event has new values and updates the display accordingly.