Adding FrontEnd Handler to a ToolStripMenuItem

The following section will guide you through this case scenario, in which you would need to add a click handler for a ToolStripItem that is implemented in the FrontEnd code (instead of triggering a request to the BackEnd).

Let's assume that the developer already has a migrated webmap app, where there is a form named Form1, it has a BindingNavigator control named bindingNavigator1 which has a ToolStripItem named newlyAddedButton.

The following file is named "form1.component.html".

<div *ngIf="model">
    <wm-window [model]="model" id="Form1" class="MigratedApp_Form1">
        <ng-template let-model>
            <div class="Form1">
                <wm-bindingnavigator #bindingNavigator1 id="bindingNavigator1" [model]="model.bindingNavigator1" class="bindingNavigator1" tabindex="1"></wm-bindingnavigator>
            </div>
        </ng-template>
    </wm-window>
</div>

To accomplish this requirement, the modifications must be done in the form1.component.ts file (showed below).

import { Component, ChangeDetectorRef, ElementRef
, Output, Renderer2, ViewEncapsulation} from "@angular/core";
import { EventData, dataTransfer} from "@mobilize/base-components";
import { FormComponent} from "@mobilize/winforms-components";
import { WebMapService} from "@mobilize/angularclient";
@Component({
   selector : "form1",
   styleUrls : ["./form1.component.css"],
   templateUrl : "./form1.component.html",
   encapsulation : ViewEncapsulation.None
})
@dataTransfer(["Form1"])
export class Form1Component extends FormComponent {
   protected webServices : WebMapService;
   constructor (wmservice : WebMapService,
   changeDetector : ChangeDetectorRef,render2 : Renderer2,elem : ElementRef) {
      super(wmservice,changeDetector,render2,elem);
   }
}
  1. Add a ViewChild (https://angular.io/api/core/ViewChild) variable in the Form1Component to reference the BindingNavigator control.

import { Component, ChangeDetectorRef, ElementRef
, Output, Renderer2, ViewEncapsulation, ViewChild} from "@angular/core";
import { EventData, dataTransfer} from "@mobilize/base-components";
import { FormComponent} from "@mobilize/winforms-components";
import { WebMapService} from "@mobilize/angularclient";
@Component({
   selector : "form1",
   styleUrls : ["./form1.component.css"],
   templateUrl : "./form1.component.html",
   encapsulation : ViewEncapsulation.None
})
@dataTransfer(["Form1"])
export class Form1Component extends FormComponent {
   protected webServices : WebMapService;
   constructor (wmservice : WebMapService,
   changeDetector : ChangeDetectorRef,render2 : Renderer2,elem : ElementRef) {
      super(wmservice,changeDetector,render2,elem);
   }
   
  @ViewChild("bindingNavigator1", { static: false })
  bindingNav: any;
}

2. Bind the AfterViewInit lifecycle hook in the Form1Component in order to add the logic needed to bind the click of the ToolsStripItem element.

import { Component, ChangeDetectorRef, ElementRef
, Output, Renderer2, ViewEncapsulation, ViewChild, AfterViewInit} from "@angular/core";
import { EventData, dataTransfer} from "@mobilize/base-components";
import { FormComponent} from "@mobilize/winforms-components";
import { WebMapService} from "@mobilize/angularclient";
@Component({
   selector : "form1",
   styleUrls : ["./form1.component.css"],
   templateUrl : "./form1.component.html",
   encapsulation : ViewEncapsulation.None
})
@dataTransfer(["Form1"])
export class Form1Component extends FormComponent implements AfterViewInit {
   protected webServices : WebMapService;
   constructor (wmservice : WebMapService,
   changeDetector : ChangeDetectorRef,render2 : Renderer2,elem : ElementRef) {
      super(wmservice,changeDetector,render2,elem);
   }
   
  @ViewChild("bindingNavigator1", { static: false })
  bindingNav: any;
  
  ngAfterViewInit(): void {
   // logic to bind the toolstripitem goes here.
 }
}

The logic goes in the AfterViewInit method because when this lifecycle hook is executed the variable used to reference the BindingNavigator control is defined with the reference to the actual BindingNavigator.

3. Add the following code on the Form1Component's ngAfterViewInit method.

 @ViewChild("bindingNavigator1", { static: false })
 bindingNav: any;
 newItemClickSub: Subscription;

 ngAfterViewInit(): void {
  this.newItemClickSub = this.bindFrontEndClickHandler('newlyAddedButton', (e) => alert('item clicked!'));
 }
 
 bindFrontEndClickHandler(itemName: string, handler: any) : Subscription {
  if (this.bindingNav) {
    const itemModel = this.bindingNav.items.filter(
      (x) => x.Name === itemName
    );
    if (itemModel.length > 0) {
      const itemComponent =
        this.bindingNav.webComponents.componentsCollection[
          itemModel[0].id
        ];
      return itemComponent.Click.subscribe(handler);
    }
  }
 }

The following is the final code.

import { Component, ChangeDetectorRef, ElementRef
, Renderer2, ViewEncapsulation, ViewChild, OnDestroy, AfterViewInit} from "@angular/core";
import { dataTransfer} from "@mobilize/base-components";
import { FormComponent} from "@mobilize/winforms-components";
import { WebMapService} from "@mobilize/angularclient";
import { Subscription } from "rxjs/internal/Subscription";
@Component({
   selector : "form1",
   styleUrls : ["./form1.component.css"],
   templateUrl : "./form1.component.html",
   encapsulation : ViewEncapsulation.None
})
@dataTransfer(["Form1"])
export class Form1Component extends FormComponent implements AfterViewInit, OnDestroy {
   constructor (private wmservice : WebMapService,
   changeDetector : ChangeDetectorRef,render2 : Renderer2,elem : ElementRef) {
      super(wmservice,changeDetector,render2,elem);
   }

   @ViewChild("bindingNavigator1", { static: false })
  bindingNav: any;
  newItemClickSub: Subscription;

  ngAfterViewInit(): void {
   this.newItemClickSub = this.bindFrontEndClickHandler('newlyAddedButton', (e) => alert('item clicked!'));
 }

 bindFrontEndClickHandler(itemName: string, handler: any) : Subscription {
  if (this.bindingNav) {
    const itemModel = this.bindingNav.items.filter(
      (x) => x.Name === itemName
    );
    if (itemModel.length > 0) {
      const itemComponent =
        this.bindingNav.webComponents.componentsCollection[
          itemModel[0].id
        ];
      return itemComponent.Click.subscribe(handler);
    }
  }
 }

 ngOnDestroy(): void {
   this.newItemClickSub?.unsubscribe();
 }
}

Once you compile the application (both Backend and FrontEnd projects), you will be able to run the app.

Last updated