Big Ali
Big Ali

Reputation: 307

How to share data between two elements in Polymer 2.0

I have the following elements, which simply has an attribute, which the element itself sets:

<link rel="import" href="../polymer/polymer-element.html">

<dom-module id="test-element-1">
  <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <h2>Hello [[prop1]]!</h2>
  </template>

  <script>
    /**
     * `test-element-1`
     * Test Element 1
     *
     * @customElement
     * @polymer
     * @demo demo/index.html
     */
    class TestElement1 extends Polymer.Element {
      static get is() { return 'test-element-1'; }
      static get properties() {
        return {
          prop1: {
            type: String,
            value: 'test-element-1',
            notify: true,
            readOnly: true
          }
        };
      }
    }

    window.customElements.define(TestElement1.is, TestElement1);
  </script>
</dom-module>

and I'd like a second element to be able to use the same data:

<link rel="import" href="../polymer/polymer-element.html">

<dom-module id="test-element-2">
  <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <h2>Hello [[prop1]]!</h2>
  </template>

  <script>
    /**
     * `test-element-2`
     * Test Element 2
     *
     * @customElement
     * @polymer
     * @demo demo/index.html
     */
    class TestElement2 extends Polymer.Element {
      static get is() { return 'test-element-2'; }
      static get properties() {
        return {
          prop1: {
            type: String,
            notify: false,
            readOnly: false
          }
        };
      }
    }

    window.customElements.define(TestElement2.is, TestElement2);
  </script>
</dom-module>

I'd like Test Element 2 to be able to get the value of prop1 from Test Element 1:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">

    <title>test-element-2 demo</title>

    <script src="../../webcomponentsjs/webcomponents-lite.js"></script>

    <link rel="import" href="../../iron-demo-helpers/demo-pages-shared-styles.html">
    <link rel="import" href="../../iron-demo-helpers/demo-snippet.html">
    <link rel="import" href="../test-element-2.html">
    <link rel="import" href="../../test-element-1/test-element-1.html">

    <custom-style>
      <style is="custom-style" include="demo-pages-shared-styles">
      </style>
    </custom-style>
  </head>
  <body>
    <div class="vertical-section-container centered">
      <h3>Basic test-element-2 demo</h3>
      <demo-snippet>
        <template>
          <test-element-1 prop1="{{prop1Value}}"></test-element-1>
          <test-element-2 prop1="{{prop1Value}}"></test-element-2>
        </template>
      </demo-snippet>
    </div>
  </body>
</html>

Here's the output of my demo though: enter image description here

What is it that I'm doing wrong?

Upvotes: 0

Views: 829

Answers (2)

Michele Dibenedetto
Michele Dibenedetto

Reputation: 575

The issue is explained by @Osifara, if you want share property with children components you need to make the top level parent a webcomponent, you need to do something like this:

<body>
    ......the other code

    <dom-module id="my-index">
        <template>
            <demo-snippet>
                <template>
                    <test-element-1 prop1="{{propIndexTest}}"></test-element-1>
                    <test-element-2 prop1="{{propIndexTest}}"></test-element-2>
                </template>
            </demo-snippet>
        </template>
    </dom-module>
    <my-index></my-index>
    ......the other code
</body>
<script>
    class MyIndex extends Polymer.Element {
        static get is() {
            return 'my-index';
        }
        static get properties() {
            return {
                propIndexTest: {
                    type: String,
                    value: 'We are sharing the same value'
                    notify: false
                }
            };
        }
    }

    window.customElements.define(MyIndex.is, MyIndex);
</script>

So now becames your top level parent container and then you can use the Polymer to work with that.

Upvotes: 0

Ofisora
Ofisora

Reputation: 2737

Since you are using index.html or any other HTML page to display the value of polymer elements, it cannot bind the value of prop1Value.

If you do same thing using a polymer-element then it will definitely work.

A property is declared implicitly if you add it to a data binding or add it as a dependency of an observer, computed property, or computed binding.

Polymer automatically creates setters for these implicitly declared properties. However, implicitly declared properties can't be configured from markup.

Upvotes: 1

Related Questions