Olof
Olof

Reputation: 544

Inheritance of web component in js files

First component : x-input. A very simple input component who do nothins :

(function() {
    class XInput extends HTMLElement {
        static get template() {
            const template = document.createElement('template');
            template.innerHTML = `
                <style>
                    :host {
                        display: block;
                    }
                </style>

                <input id="input">
            `;
            return template;
        }

        constructor() {
            super();
            this.attachShadow({mode: 'open'});
            this.shadowRoot.appendChild(XInput.template.content.cloneNode(true));
        }
    }

    window.customElements.define('x-input', XInput);
})();

My component is in a .js file so I don't need to use HTML Import in my client page. Now, I need a second web component who inherit from x-input :

(function() {
    class XInputNumber extends XInput {

    }

    window.customElements.define('x-input-number', XInputNumber);
})();

If I try to use this second element in a page -> Uncaught ReferenceError: XInput is not defined.

<html>
    <head>
        <script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
        <script src="/bower_components/shadydom/shadydom.min.js"></script>

        <script src="/webcomponents/input/x-input.js"></script>
        <script src="/webcomponents/input/x-input-number.js"></script>
    </head>
    <body>
        <p><x-input></x-input></p>
        <p><x-input-number></x-input-number></p>
    </body>
</html>

If i write my web components in html files, no problem, but I have to use HTML Imports (I try to do without it).

How can I achieve this ?

Upvotes: 1

Views: 1715

Answers (2)

Dotista
Dotista

Reputation: 431

export default class ChildComponent extends ParentComponent {
  constructor() {
    super("child template");
  }

  connectedCallback() {
    super.connectedCallback();
  }
}

customElements.define('x-child', ChildComponent);

Parent component:

export default class ParentComponent {
  constructor(childTemplate) {
    this.appendChild('foo<div class="refChildContent"></div>bar');
    this.childTemplate = childTemplate;
  }

  connectedCallback() {
    this.querySelector('.refChildContent').innerHTML = this.childTemplate;
  }
}

customElements.define('x-parent', ParentComponent);

Result:

<x-child>
 foo
 <div class="refChildContent">
    child html
 </div>
 bar
</x-child>

Upvotes: 0

Supersharp
Supersharp

Reputation: 31219

As you noticed, the XInput class is define only in the closure. If you want to reuse it somewhere else you can define it globally, or retreive it with the help of customElements.get() method.

In x-input-number.js file:

(function() {
    var XInput = customeElements.get('x-input');

    class XInputNumber extends XInput {

    }

    window.customElements.define('x-input-number', XInputNumber);
})();

or directly:

class XInputNumber extends customeElements.get('x-input') {}

Upvotes: 2

Related Questions