Gbeschbacher
Gbeschbacher

Reputation: 456

Polymer - dynamic template rendering

is it somehow possible to render the template in a polymer element dynamically at runtime or when some light-dom elements are available? I have the following situation:

index.html

<mega-menu>
  <span class="menuTriggerText">Open Menu</span>
  <ul class="test">
    <li>TEST1</li>
    <li>TEST2</li>
  </ul>
  <ul class="test">
    <li>TEST1</li>
    <li>TEST2</li>
  </ul>
</mega-menu>

in my polymer-element.html i want to do something as follows:

<template>
  <template repeat="{{temp}}"><p>I want to try this</template>
</template>

Polymer('mega-menu, {
  created:function(){},
  ready: function(){
    //getting markup from light-dom
    this.temp = document.getElementsByClassName('test');
  },
  attached:function(){},
  detached: function(){},
  attributeChanged: function(attrName, oldVal, newVal){}
});

Now, my question is - how do i get this to work? do i need to bind something on my template? or do i need some kind of event-listener or observer on something?

Thanks, Gbeschbacher

Upvotes: 2

Views: 4076

Answers (1)

ebidel
ebidel

Reputation: 24109

This is precisely what content insertion points are for. You can select top-level light DOM markup to render at specific locations in the Shadow DOM. <content select=""></content> takes a CSS selector and grabs nodes from the light DOM.

Your example would be:

<polymer-element name="mega-menu" noscript>
  <template>
    <content select=".test"></content>
  </template>
</polymer-element>

You should not need to pry into the light DOM like this for such a simple case, but for the sake of completeness, we can get your example working with a few important tweaks:

  1. document.getElementsByClassName('test') looks for nodes in the entire document. This is not what you want. You only want children of <mega-menu>. Instead of document use this (e.g. this.querySelectorAll('.test')).
  2. You're giving <template repeat="{{temp}}"> a NodeList. It won't be able to stamp that out. It expects an Array. Something like this.temp = [].slice.call(this.querySelectorAll('.test')); would work.

http://jsbin.com/balodowi/2/edit

Upvotes: 2

Related Questions