Custom Basemap Toggle with ArcGIS JavaScript API 4 View Models

I’m super excited about the ArcGIS API for JavaScript 4.0 beta. One of the exciting things is developer friendly widgets which allows us to write our own presentation layer, and still use the logic of the core widget (the “View Model”). For example, the View Model for the Basemap Toggle Widget allows you to call toggle() and get the current/secondary basemaps, all from your own module that implements the view.

After reading through Odoenet’s great post on this subject, I thought I’d take his React example and throw together an equivalent view in Dojo.

In the postCreate function we’re setting up a watch (using dojo/stateful) and updating our thumbnails when we see the “secondaryBasemap” property change. The event for when the user clicks the thumbnail is using dijit/_TemplatedMixin to setup that event to call the toggle function when it is clicked. In our toggle function we’re just calling the View Model’s toggle function.

var BToggle = declare([_WidgetBase, _TemplatedMixin, Stateful], {
  
  	// https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L75-L78
  	templateString: '<div><div class="basemap-item basemap-item-secondary" data-dojo-attach-event="click:toggle" data-dojo-attach-point="secondaryBasemapItem"></div><div class="basemap-item basemap-item-current" data-dojo-attach-point="currentBasemapItem"></div></div>',
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L5-L9
    bgImage: function(target, url) {
    	domStyle.set(target, 'background-image', 'url(' + url + ')');
    },
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L13-L18
    constructor: function() {
      this.inherited(arguments);
      this.vm = new BasemapToggleVM();
      this.secondaryThumbnailUrl = '';
    },
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L29-L50
    postCreate: function() {
    	this.inherited(arguments);
      this.vm.view = this.view;
      this.vm.secondaryBasemap = this.secondaryBasemap;
 
      var info = this.vm.getBasemapInfo(this.secondaryBasemap || 'topo');
      this.updateThumbnails(info, this.vm.currentBasemap);
      this.vm.watch('secondaryBasemap', lang.hitch(this, 'updateThumbnails'));
    },
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L52-L59
    updateThumbnails: function(secondary, current) {
      var secInfo = this.vm.getBasemapInfo(secondary);
      var curInfo = this.vm.getBasemapInfo(current);
    	this.bgImage(this.secondaryBasemapItem, secInfo.thumbnailUrl);
      this.bgImage(this.currentBasemapItem, curInfo.thumbnailUrl);
    },
    
    // https://github.com/odoe/esrijs4-vm-react/blob/master/src/components/basemaptoggle.jsx#L61-L63
    toggle: function(evt) {
    	this.vm.toggle();
    }
  });

The code is annotated with links back to the equivalent line numbers in Rene’s example. This was a great learning experience for learning the View Models concept in the JS API - I’d encourage you to write your own!

See Also