0👍
So in the end I solved this by using normal classes instead of mixins. I also used bottlejs for dependency injection.
Now each class in its constructor specifies other classes, that it needs to use, so it is immediately clear which classes it is dependent on.
Also before when one mixin needed to call other mixin’s method, it was a simple this.methodName()
call with no knowledge about where this method is located, whereas now it is clearly stated by this._otherClass.methodName()
Since I needed access to canvas, store and also to emit events, I created class Editor, that has a method init(canvas, store, eventBus)
, because I can only create the Fabric canvas, after the HTML canvas is displayed. Bottle creates this class with empty fields and I call the init function with the parameters in mounted stage of my component.
All of my classes are then ancestors of EditorProvider class, which only has one getter for this Editor class (that it gets in a constructor and stores in a field), from where I can get any of the specified fields. So the call to store in any of my classes looks like:
this.editor.store.commit('anything')
Call to canvas:
this.editor.canvas.renderAll()
Call to eventbus:
this.editor.eventBus.emit('eventName')
My component now just imports the bottlejs and has access to all the classes by their names. The interaction is mainly by the canvas and window events, so I event created an EventHandler class, that moves all these event listeners from the component to separate class. So in the end in the component I only have HTML template and a few lines of imports and the script tag, which is now much more readable and the dependencies are clearly visible.