aurelia / templating

An extensible HTML templating engine supporting databinding, custom elements, attached behaviors and more.
MIT License
116 stars 104 forks source link

Custom elements with common base class #681

Open lorond opened 4 years ago

lorond commented 4 years ago

Submitting a bug report

Current behavior: Several custom elements cannot inherit the same base class (please, do not close issue at this point, at least, read the "Desired behavior" section first).

Repo that reproduces bug: https://github.com/partyzzzan/extend-err-app Note, the 1st commit represent a bug (git checkout bug), the 2nd and the 3rd commits are possible workarounds.

When you open root, Home custom element is rendered: image

Let's click open foo - it opens FooContainer that in turn contains FooItem: image

Let's get back to home and then go to bar - it opens BarContainer that in turn contains BarItem: image

Nothing rendered and no any errors in console: image

Both BarItem and FooItem extends same generic SomeComponentBase<TModel>

But let's get back to foo again: image

Note, bar's template rendered with foo's model.

Two possible workarounds:

  1. do not use inheritance
  2. explicitly decorate FooItem and BarItem with @customElement decorator

Desired behavior

As of #463 (and other issues) I guess, this one should not be closed without fix. The issue is not about the behavior itself, but about the fact, that there is no any errors in console or anything else, no information at all for developers - what happened or what to do.

It would be nice to have something like:

Use decorators, not inheritance.

(c) https://github.com/aurelia/templating/issues/463#issuecomment-264192090

bigopon commented 4 years ago

@lorond I believe you hit the issue of derived class retrieving base class metadata. We have provided doc for this, but probably it's easy to miss. Did you have a look at https://aurelia.io/docs/templating/html-behaviors#inheritance-with-html-behaviors? Note:

Second, notice that we explicitly declared @customElement(). Any time you inherit a custom element, you must add the customElement decorator.

It doens't need to be a @customElement decorator though, any metadata-stamping decorator would do: @bindable, @useShadowDOM, @templateController etc...

Here's some example you can have a look at: https://discourse.aurelia.io/t/example-of-binding-inheritance/428

@jods4 @EisenbergEffect @fkleuver We can fix this behavior of inheritance, that is surprising users here and there with probably a simple change: get own metadata instead of first available metadata in the hierarchy. Though I'm not sure the potential breaking changes, but it seems to me anything that is not working would suddenly work. Not sure if it's a good idea. Thoughts?

lorond commented 4 years ago

Thanks @bigopon. Yep, I missed that. I'll do a PR a bit later to highlight this in the docs, ok?

bigopon commented 4 years ago

@lorond that'd be awesome