ESRI JS API : extend with mixins

941
6
12-14-2019 03:05 AM
NicolasGIS
Regular Contributor

Hello,

Is there any working example for extending a class with mixin ?

According to the documentation, "Extending multiple classes is deprecated at 4.13". So I try to migrate a class extending accessor and evented. I used to have this piece of code in my class:

Implementing Accessor | ArcGIS API for JavaScript 4.13 

import Evented = require("dojo/Evented");

import Accessor = require("esri/core/Accessor");

import { subclass, declared } from "esri/core/accessorSupport/decorators";

interface Collection extends Evented {}

@subclass("esri.guide.Collection")

class Collection extends declared(Accessor, Evented) { }

But following the new example, I don't quite understand:

Implementing Accessor | ArcGIS API for JavaScript 4.13 

I do not wan't to define my own "emit" and "on" functions but rather use the one from dojo evented. 

To me both examples are not equivalent. It would be nice to have a more detailed example !

Thanks

Tags (2)
0 Kudos
6 Replies
YannCabon
Esri Contributor

Hi Nicolas,

By removing `declare` we can't anymore extend both dojo's classes and Accessor for example. As a matter of fact the API is using its own version of Evented as a mixin, which is not from Dojo.

There is a couple of quick ways you can mix in Evented from Dojo while extending Accessor. Since `dojo/Evented` is a very simple class with no constructor and internal state, the fastest solution is to use directly the functions from `dojo/Evented`.

require([
  "esri/core/Accessor",
  "dojo/Evented"
], (Accessor, Evented) => {
  function EventedMixin(Base) {
    return Base.createSubclass({
      on: Evented.prototype.on,
      emit: Evented.prototype.emit
    })    
  }
  
  var MyClass = EventedMixin(Accessor);
  var instance = new MyClass();
  
  instance.on("event", () => console.log("event received"));
  instance.emit("event");
});

Here I created a mixin EventedMixin which creates a subclass of the provided Base and which adds the on and emit methods from dojo/Evented.

Another option would be to copy the implementations from dojo in the mixin instead of referencing them.

Thanks

Yann

NicolasGIS
Regular Contributor

Hi Yann Cabon,

Many thanks for your detailed explanation. It is much clearer now. Very much appreciated.

Investigating this issue, I wondered why is your implementation of "Evented" (esri/core/Evented) not publicly adviced as I think the "EventedAccessor" class would be very nice to have out of the box when developing widget.

Thanks for listening !

YannCabon
Esri Contributor

That's a good question. esri/widgets/Widget already extends esri/core/Evented actually. It's not documented to let us make any modifications faster. When a module is documented we need to support it and any modification would go through deprecation etc. (we are still trying to improve the deprecation/change process). esri/core/Evented changed as the multi-inheritance was removed for example. I managed to get this done in a single release cycle. If the module had been public it wouldn't have been possible.

NicolasGIS
Regular Contributor

Many thanks for this explanation. I now understand the reason. Maybe when core will get more stable then ! Out of curiosity, what will be the main advantage of getting rid of "declare" as the whole API is based on dojo ?

0 Kudos
YannCabon
Esri Contributor

The whole API is barely based on dojo now and declare is just one of the last things to stop using from dojo.

NicolasGIS
Regular Contributor

Interesting ! Now that you say it, I realize it 

Many thanks for these explanations

0 Kudos