Search code examples
polymershadow-dom

Polymer custom element attribute access or send


I'm searching for a way to access an attribute on a Polymer custom element from the DOM or to send data from Polymer.register to the DOM.

This really simple element below takes two values and multiplies them, placing the result in its result attribute.

How can I access this result from the outside?

<element attributes='value times result' name='value-box'>
  <template>
    <p>{{result}}</p>
  </template>

  <script>
    Polymer.register(this, {
      ready: function() {
        if (this.value != null && this.times != null) {
          this.result = this.value * this.times;
        }
      }
    });
  </script>
</element>

Solution

  • result is a property on your element just like times and value. You can access it from outside JS, as you would any property on a normal HTML element. For example:

    <value-box value="2" times="10"></value-box>
    <script>
      document.querySelector('value-box').result;
    </script>
    

    Internal to your element, what you want is to keep the result computed property up to date as times/value change. There are a couple of ways to do that. One is to use <property>Changed watchers [1]:

    <element name="value-box" attributes="value times result">
      <template>
        <p>result: {{result}}</p>
      </template>
      <script>
      Polymer.register(this, {
        valueChanged: function() {
          this.result = this.value * this.times;
        },
        timesChanged: function() {
          this.result = this.value * this.times;
        }
      });
      </script>
    </element>
    

    Demo: http://jsbin.com/idecun/2/edit

    Alternatively, you can use a getter for result:

      Polymer.register(this, {
        get result() {
          return this.value * this.times;
        }
      });
    

    Demo: http://jsbin.com/oquvap/2/edit

    Note For this second case, if the browser doesn't support Object.observe, Polymer will setup a timer to dirty check result. This is why you see "here" printed in the console for this second example. Run the same thing in Chrome Canary with "Experimental WebKit features" enabled in about:flags, and you won't see the timer. Yet another reason why I can't wait for Object.observe to be everywhere! :)

    Hope this helps.