Over the last few weeks I’ve been trying to refactor a codebase to use superclasses and inheritance more in my components. I’ve run across a very odd scenario which appears to be a bug regarding the use of @bindable inside the superclass. Here’s the simplest reproduction I was able to do:
The setup is simple:
I’ve got two components, X and Y. They both extend from an abstract base class, Base.
If you run this example you’ll see that only X is displayed. If you comment out the line requiring X, Y will be displayed. But both seemingly can’t be required and displayed at the same time.
Now, it gets more confusing and interesting when we use require as instead of require. In this case we get 2 instances of X. One when we require X under an alias, and one when we require Y as an alias. Somehow, Y is being loaded as X.
If you comment out the @bindable property in Base, everything works as it should. It appears very much that the bindable property is causing the problem.
Can you guys explain why you’re even going the baseclass route with inheritance? It is a more or less general consensus nowadays to prefer composition over inheritance so I wonder what your specific requirement was.
Copying the @bindable is working in my repro!! Thanks for the help I’m going to try it in production and verify my problems are solved.
Here’s a link to a branch with the fix for anyone curious:
@zewa666 I chose to use inheritance mostly because it solves the problems I’ve been facing with repeated code in a way that makes sense to me. In our codebase we have a lot of data types and each one requires a set of custom elements (summary cards, custom select boxes, forms, reporting widgets… the list goes on) and while they’re all a bit different most of the base functionality of each type is the same. All of our selectors listen for the same events and have the same bindings, for instance, but have different ways of searching, filtering and displaying their entities.
I’ve experienced issues in the past with inheritance and custom elements. Have you tried @customElement() on your derived components? There’s a section of the docs which covers inheritance which might be able to assist you.
@Krussicus I’ve seen that doc as well - but have still needed to repeat the bindable property, decorator and all, in the implementing @customElement-decorated class.