This is indeed an ugly problem that I've faced when making Custom
Elements. The problem is: in templates, custom elements do not get
"upgraded" into their identity. They only get "upgraded" once they are
inserted into the live DOM.

The best you can do is make deferred code in your custom element
constructor to check for existing property values before overriding
them with getters/setters, and make sure to store the already-existing
values.

It would also help for your elements to emit a "ready" event, or
similar, once the constructor has fired, and consumer code can listen
for this event (on a parent element where it has bubbled to) to
finally begin using any of the custom element's APIs.

Yes, this is very ugly. I really dislike this about custom elements.
But once you learn how to abstract it, then you'll be beyond the
problem. Libraries like Polymer, SkateJS, etc, abstract this stuff
away, so that if you stick with their recommended APIs, you don't hit
the issue.

But yeah, discourse.wicg.io is a good place to ask. Another good place
to ask, where all vendors talk about the spec, is
github.com/w3c/webcomponents/issues.

All the best,
- Joe


On Tue, Sep 24, 2019 at 9:39 AM Isiah Meadows <[email protected]> wrote:
>
> You'd have better luck in https://discourse.wicg.io than here. This is about 
> the ECMAScript spec and JavaScript the language, not anything related to the 
> web platform at large.
>
> On Tue, Sep 24, 2019 at 09:55 Randy Buchholz <[email protected]> wrote:
>>
>> I’m putting a custom element in a template and then “selecting” it out to 
>> Window level. It seem to loose its identity as a custom element.
>>
>>
>>
>> ```
>>
>> // In page
>>
>> <template id="holder">
>>
>>     <my-element field="A"></my-element>
>>
>> </template>
>>
>>
>>
>> <script type="module">
>>
>>     class MyElement extends HTMLElement {
>>
>>         constructor() {
>>
>>             super();
>>
>>         }
>>
>>         get Field() { return this.getAttribute("field");}
>>
>>     }
>>
>>
>>
>>     window.customElements.define("my-element", MyElement);
>>
>> </script>
>>
>>
>>
>> <script>
>>
>>     const frag = document.querySelector("#holder").content;
>>
>>     const el = frag.querySelector("my-element");
>>
>>     console.log({el});
>>
>> </script>
>>
>> ```
>>
>>
>>
>> When `<my-element>` is a page level and not in a template I can read 
>> `xxx.Field`. When it comes from within a template it seems to no longer act 
>> like the custom element – xxx.Field isn’t defined. The script selecting it 
>> is at “Window” level, so shouldn’t it “cast” correctly?
>>
>> _______________________________________________
>> es-discuss mailing list
>> [email protected]
>> https://mail.mozilla.org/listinfo/es-discuss
>
> --
> -----
>
> Isiah Meadows
> [email protected]
> www.isiahmeadows.com
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to