lgersman
lgersman

Reputation: 2286

How to pass required attributes to element constructor

i have a polymer custom element like this

<script src="http://www.polymer-project.org/platform.js"></script>
<script src="http://www.polymer-project.org/polymer.js"></script>

<polymer-element name="my-foo" constructor="MyFoo" attributes="controller" noscript>
    <template>
      hello from {{options.name}}
    </template>
    <script>
      Polymer({
        get options() {
          return this.controller.options;
        }
      });
    </script>
</polymer>

<div id="container"></div>

<script>
  document.addEventListener('polymer-ready',function() {
    var foo = new MyFoo();
    foo.controller = {
        options : {
            name : "here"
       }
    };
    document.body.appendChild(foo);
  });
</script>

attribute "controller" is expected to be a object having a property "options" of type object.

I can create a Instance of the custom element using

var foo = new Foo();

but i am unable to set the attribute "controller" which results in an error:

Uncaught TypeError: Cannot read property 'options' of undefined.

Sure - i could modify the options getter in the polymer component to be fail-safe like this :

...
get options() {
    return this.controller ? this.controller.options : null;
}
...

But also in this case the custom element doesnt recognize the applied data.

Final question : How do I pass required attributes to an custom element constructor ?

Upvotes: 2

Views: 1486

Answers (1)

Peter Burns
Peter Burns

Reputation: 45361

One solution is to use a computed property:

<script src="http://www.polymer-project.org/components/platform/platform.js"></script>
<link rel='import' href='http://www.polymer-project.org/components/polymer/polymer.html'>

<polymer-element name="my-foo" constructor="MyFoo" attributes="controller" noscript>
    <template>
      hello from {{options.name}}
    </template>
    <script>
      Polymer({
        computed: {
          options: 'controller.options'
        }
      });
    </script>
</polymer-element>

<script>
  document.addEventListener('polymer-ready',function() {
    var foo = new MyFoo();
    document.body.appendChild(foo);
    foo.controller = {
      options : {
        name : "here"
      }
    }
  });
</script>

You can even make the computed property just a call to a method. The key thing is that by doing it this way, Polymer can tell when to check if options has changed, because it knows the inputs necessary to compute options.

Polymer({
  computed: {
    options: 'getOptions(controller)'
  },
  getOptions: function(controller) {
    return controller ? controller.options : null;
  }
});

Upvotes: 2

Related Questions