posit labs
posit labs

Reputation: 9431

Dynamically publish attributes in Polymer

Is it possible to publish new Polymer component attributes at runtime?

<polymer-element name="dynamic-attributes">
    <template></template>
    <script>
        Polymer('dynamic-attributes', {
            ready: function(){
                var attributes = new Thing().getAttributes();
                this.publishAttributes(attributes); // imaginary method         
            },
        });
    </script>
</polymer-element>

More info...

I'm writing a component lib that wraps Seriously.js.

Here is an example of the ideal implementation.

<seriously-graph linear>
    <seriously-source>
        <img src="images/pencils.jpg">
    </seriously-source>
    <seriously-effect type="pixelate" pixelSize="{{pixelSize}}"></seriously-effect>
    <seriously-effect type="blur" amount=".5"></seriously-effect>
    <seriously-target width="411" height="425"></seriously-target>
</seriously-graph>

I have a work-around that uses MutationObserver to detect attribute changes. It works, but then I have to find a solution for serialization and make property getters/setters. It feels like I'm re-inventing the wheel (Polymer), and was hoping there was a built-in method of doing this.

Upvotes: 1

Views: 947

Answers (3)

user2672083
user2672083

Reputation: 375

Here's a Gist that does what you're looking for. Basically, it dynamically creates a concrete <polymer-element> for an effect the first time it's used, and then swaps the generic instance with a dynamically created concrete one, copying any binding declarations in the process. The source would be:

<seriously-effect type="blur" amount="{{someAmount}}"></seriously-effect>

But with Inspect Element, you'd see:

<seriously-effect-blur amount="{{someAmount}}"></seriously-effect-blur>

Upvotes: 1

wirlez
wirlez

Reputation: 388

Maybe you could make a global array and use it as attribute?

<polymer-element name="app-globals" attributes="values">
  <script>
    (function() {
      var values = {};

      Polymer({
         ready: function() {
           this.values = values;
           for (var i = 0; i < this.attributes.length; ++i) {
             var attr = this.attributes[i];
             values[attr.nodeName] = attr.value;
           }
         }
      });
    })();
  </script>
</polymer-element>

<app-globals id='myDynamicFunctions' someFunction someOtherFunction></app-globals>

<script>
    //then define it
    document.$.myDynamicFunctions.values.someFunction = function(){...}
</script>

I am not quite sure what you are looking for, this might give you a hint...

Upvotes: 0

Max Zuber
Max Zuber

Reputation: 1229

Yes, it is possible by assigning an attributes object to publish node. See https://www.polymer-project.org/docs/polymer/polymer.html#attributes for details.

Your method must return an object of attributes:

Polymer('dynamic-attributes', {
  publish: (new Thing()).getAttributes() || {}
});

Upvotes: 0

Related Questions