DataManagerEvents

All the events that are triggered by the columns inside a data manager are handled by the Data Manager Control, that is a special kind of component to render the migrated PowerBuilder's Data Windows controls in the WebMap application.

This emulates the way that the original Power Builder's DataWindow Control handles all the events triggered by every column that is displayed inside it.

The Data Manager Event Service

This service was created to report the event triggered by a DataManager column to the DataManager control. It works using a simple publish-subscriber pattern between the column component and the DataManager Control

How to use the service:

This service must be injected by every column component constructor and it provides the required function to report to the DataManager container component the event data that we want to report.

export class ColumnControlComponent extends BaseControlComponent
  implements OnInit, AfterViewInit, MaskFormat {
  constructor(
    private changeDetectorColumn: ChangeDetectorRef,
    private rendererColumn: Renderer2,
    private elementColumn: ElementRef,
    Optional() private emitterColumn: DataManagerEventService,
    @Optional() private maskFormat: MaskFormatService
  ) {
    super(changeDetectorColum, rendererColumn, elementColumn, emitterColumn);
  }

The emitterColumn property in this example is used to report to the nearest DataManagerContainer an event that just occurred in the current ColumnControlComponent.

Perhaps, you note that the emitterColumn is an Optional dependency, that's because the current component could be use outside a DataManagerControl component and then there is no provider for the DataManagerEventService.

Since the window components could be used inside a DataManagerControl component those components should have an instance of the DataMangerEventService too.

To report an event we create a function that evaluates first if the service dependendency is instantiated and then it reports the event to the DataManagerControl if it is required:

  /**
   * @description
   * Propagates the event to the parent DataControl if required.
   * @param eventName The original server event name.
   * @param data The collected information for the current event.
   */
  emitDataManagerEvent(eventName: string, data: EventData): void {
    if (this.dataManagerEmitter) {
      this.dataManagerEmitter.emitEvent(eventName, data);
    }
  }

The function emit event is used to set the Observable field that is used to notify the service provider that an event have been triggered.

    /**
     * Sends an event change from inner component
     * to parent DataControl
     * @param serverEventName the original server event name.
     * @param data The current data collected for this event
     */
    emitEvent(serverEventName: string, data: EventData): void {
        if (data.event) {
            data.event.serverEvent = serverEventName;
            this.eventEmitted.next(data);
        }

The emitEvent receives the event name and the event data that should be send to the DataManagerControl component in order to report the event to the server side. It uses the eventEmitted observable that is a Angular's Subject field that is used as the EventEmitter to report the events to the DataManagerControl.

The DataManagerControl component

This component is the provider for the DataManagerEventService so any component that is rendered inside this component should have a defined instance of that service and every emitted event should be handled by this component.

ngOnInit(): void {
    super.ngOnInit();
    this.emitter.events.subscribe(event => this.eventsHandler(event));
  }

Then, after an event is reported the subscriber calls the eventsHandler that verifies if there is a handler for the reported event name and then calls the correspondin function that send the event command to the server side if it is required using the @serverEvent decorator as usual in WebMap's applications.

 /**
   * @description
   * Invoke the corresponding handling for data window control
   * events
   * @param event The collected event information.
   */
  eventsHandler(event: EventData): void {
    if (event.event.serverEvent) {
      this.setDelay(false);
      switch (event.event.serverEvent) {
        case 'clicked':
        case 'buttonclicked':
          this.clickEventHandler(event);

The events for the DataManager are handled this way because the DataManagerControl is the component that currently knows what events are binded and requires to notify the server side, using this approach we can actually reduce the amount of requests made to the server side for each component.