0

I have a Parent file index.js that renders child tag counter.js. Whenever a property in child is changed a event is triggered and parent listens it. For this to work, I have to render both tags in index.html else index.js is unable to listen as querySelector fetching Null value. I want to avoid using x-counter tag in index.html. Please have a look at the files in the below link: https://stackblitz.com/edit/js-fxhcp8

Here are my 3 files:

//1) index.js (Parent)
class XApp extends PolymerElement {
  constructor() {
    super();
    this.a = 15;
  }

  ready(){ 
    console.log("Done");
    super.ready();
    document.querySelector('x-counter').addEventListener('valueChange',function(e){
      console.log(e);
    });
}
  static get template() {
    return html`
     <x-counter></x-counter>
    `;
  }
}

customElements.define('x-app', XApp);

//2) counter.js (Child)
import { LitElement, html, property } from '@polymer/lit-element';

class XCounter extends LitElement {
  static get properties() {
    return {
      value: { type: Number }
    }
  }

  constructor() {
    super();
    this.value = 0;
  }

  render() {
    return html`
      <style>
        button, p {
          display: inline-block;
        }
      </style>
      <button @click="${() => this.decrement()}" aria-label="decrement">-</button>
      <p>${this.value}</p>
      <button @click="${() => this.increment()}" aria-label="increment">+</button>
    `;
  }

  decrement() {
    this.value--;
    this._valueChanged();
  }

  increment() {
    this.value++;
    this._valueChanged();
  }

  _valueChanged() {
    this.dispatchEvent(new CustomEvent('valueChange', { detail: this.value }));
  }
}

customElements.define('x-counter', XCounter);

//index.html
<!doctype html>
<html>
  <body>
<!-- Error without the below tag-->
      **<x-counter></x-counter>**
    <br />
    <x-app></x-app>
  </body>
</html>
Yodha
  • 45
  • 9

1 Answers1

0

Here is a working example : I edit your code. Your code almost ready, I did just small changes:

DEMO

import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';

import './x-counter.js';

class IndexApp extends PolymerElement {
   constructor() {
    super();
    this.a = 15;
    this.addEventListener('value-changed', this._valueChanged)
  }

  static get template() {
    return html`
     <div>Parent element value : [[a]]</div>
      <x-counter 
         val="{{a}}" > 
      </x-counter>
    `;
  }
  _valueChanged(x){
      this.set('a', x.detail.val);
  }
}
customElements.define('index-app', IndexApp);

And x-counter is:

import {LitElement, html, property} from '@polymer/lit-element';

class XCounter extends LitElement {
  static get properties() {
    return {
      val: { 
        type: Number 
        }
    }
  }

  render() {
    return html`
      <style>
        button, p {
          display: inline-block;
        }
      </style>
        <div id="div1">Hi</div>
        <div id="div2">This is a Lit </div>


      <button @click="${this.decrement}" aria-label="decrement">-</button>
      <p>value: ${this.val}</p>
      <button @click="${this.increment}" aria-label="increment">+</button></body>
    `;
  }

  decrement() {
    this.val--;
  }

  increment() {
    this.val++;
  }


  updated(props) {
    console.log("generated event", props);
    this.dispatchEvent(new CustomEvent('value-changed', {  bubbles: true, composed: true, detail: {val:this.val} }));

  }
}

customElements.define('x-counter', XCounter);
Cappittall
  • 3,300
  • 3
  • 15
  • 23