Jochen Kühner Jochen Kühner - 1 month ago 11
Javascript Question

Polymer : Watch the changed Property from outside of an Component

I've Polymer Webcomponent.

My problem is now, outside of the Component I use knockout for DataBinding scenarios. Now I wanted to create my own Knockout Binding Type, wich is able to use twoWay-Binding with Poylmer objects. For this I need to subscribe to the Property observer from outside of the component. Is this possible? when, how?

Answer

Yes, it's possible to subscribe to property-change notifications when the Polymer property has notify: true.

Property change notification events (notify)

When a property is set to notify: true, an event is fired whenever the property value changes. The event name is:

_property-name_-changed

Where property-name is the dash-case version of the property name. For example, a change to this.firstName fires first-name-changed.

These events are used by the two-way data binding system. External scripts can also listen for events (such as first-name-changed) directly using addEventListener.

For more on property change notifications and the data system, see Data flow.

So, if you wanted to subscribe to <x-foo>.bar externally to interop with Knockout, you could use addEventListener() for the bar-changed event:

var foo = document.querySelector('x-foo');
foo.addEventListener('bar-changed', function(e) {
  console.log('new bar:', e.detail.value);
});

HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',
    properties : {
      bar: {
        type: String,
        value: 'Hello world!',
        notify: true
      }
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.7.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>
<body>
  <x-foo></x-foo>
  <script>
    window.addEventListener('WebComponentsReady', function() {
      var foo = document.querySelector('x-foo');
      foo.addEventListener('bar-changed', function(e) {
        console.log('new bar:', e.detail.value);
      });
      
      foo.bar = 'hey';
      foo.bar = 'there!';
    });
  </script>

  <dom-module id="x-foo">
    <template>[[bar]]</template>
  </dom-module>
</body>

codepen