Question

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>
Was it helpful?

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.

OTHER TIPS

Just wanted to add a useful follow up to this (Even though the question has been answered).

My follow up is in response to the following comment on the actual answer:

I'm curious as to why selection with jQuery didn't work. Does it not recognize Custom Elements? – CletusW Jul 8 '13 at 19:57

The most likely reason jQuery didn't see your element is because it was not fully formed by the browsers run time at that point.

I ran into this problem while developing my ASP.NET MVC + polymer js sample app on my github page, and essentially what I was trying to do was call methods and access properties on my polymer object before polymer had made everything usable.

Once I moved the code I was using into a button click (So I could trigger it manually after I visually could see my component was ready) everything worked fine.

For now, if you try to access anything too soon, EG: in your jQ doc.ready handler, there's a good chance you'll run into all sorts of daft problems like this.

If you can find a way of delaying your action, or even better using polymer signals to signal from the components ready handler to an outside agent, that sets a flag telling you the component is ready, then you can sort this easily.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top