confusedandconfusing
confusedandconfusing

Reputation: 119

How to pass unknown children of Polymer component into component's DOM

I want to create a component which I can pass other components to and create DOM structures.

<test-component>
    <img/>
    <div/>
    <foo/>
</test-component>

In trying to get that working:

<dom-module name="test-component">
    <template>
        <h1>Title</h1>
        <ul>
            <template is="dom-repeat" items="{{nodes}}">
                <li>element:</li>
                <li>{{item}}</li>
            </template>
        </ul>

        <content id="contentelement"></content>
    </template>
</dom-module>

<script type="text/javascript">
    Polymer({
        is: "test-component",
        ready: function() {
            this.nodes = (function(that) {
                var nodeList = that.$.contentelement._distributedNodes,
                    nodeMap = [];
                for(var i = 0; i < nodeList.length; i++) {
                    if(nodeList[i].nodeType === 1) {
                        nodeMap.push(nodeList[i].outerHTML);
                    }
                }
                return nodeMap
            }(this));
        }
    });
</script>

I used a function to build this.nodes because this.nodes = this.$.contentelement.getDistributedNodes(); returns null, not sure why.

I know you can't just drop an element's outerHTML into the page but can a random set of HTML/components be passed into a template like this?

Upvotes: 2

Views: 363

Answers (1)

Maria
Maria

Reputation: 5604

Unfortunately this is currently not possible with data-binding (have a look at this discussion on Github).

Here's a possible workaround in JavaScript.

<dom-module name="test-component">
    <template>
        <h1>Title</h1>
        <ul>
            <template is="dom-repeat" items="{{nodes}}">
                <li>element:</li>
                <li class="content"></li>
            </template>
        </ul>
        <content id="contentelement"></content>
    </template>
</dom-module>

<script type="text/javascript">
    Polymer({
        is: "test-component",
        ready: function() {
            this.nodes = this.getContentChildren();
            this.async(function(){
                var contentNodes = Polymer.dom(this.root).querySelectorAll(".content");
                this.nodes.forEach(function(element, index) {
                    contentNodes[index].innerHTML = element.outerHTML;
                });
            }.bind(this));
        }
    });
</script>

Edit

You can remove the content nodes from their original location after you have accessed them by removing them from the DOM.

this.nodes = this.getContentChildren();
Polymer.dom(this.root).removeChild(this.$.contentelement);

Upvotes: 1

Related Questions