I am attempting to build generic web components that render JSON object collections, like a tree view and a multi-list view (moving items between two lists). I would like to copy the pattern used by iron-list where a template containing the individual item presentation is passed into the component for reuse.
For example, given this web component template:
<dom-module id="intworkspace-tree">
<template>
<style include="iron-flex iron-flex-alignment">
paper-icon-item {
--paper-item-min-height: var(--intworkspace-tree-margin,30px);
--paper-item-icon-width : var(--intworkspace-tree-margin,30px);
}
paper-icon-item:focus::before,
paper-icon-item:focus::after {
color: inherit;
opacity: 0;
}
.node {
margin-left: var(--intworkspace-tree-margin,30px);;
}
</style>
<slot id="labelView"></slot>
<template id="nodeView">
<div class="layout vertical">
<paper-icon-item on-tap="nodeSelected">
<iron-icon icon="expand-less" slot="item-icon" hidden$="[[!hasNodes(node)]]"></iron-icon>
<!-- label goes here-->
</paper-icon-item>
<iron-collapse class="node" opened hidden$="[[!hasNodes(node)]]">
<intworkspace-tree tree="[[node.nodes]]" embedded></intworkspace-tree>
</iron-collapse>
</div>
</template>
</template>
...
</dom-module>
and this usage:
<intworkspace-tree tree="{{testTree}}">
<template><paper-item-body>[[node.name]]</paper-item-body> </template>
</intworkspace-tree>
Utilize the Polymer.Templatize.templatize API to load the templates, create/stamp new instances, and use the DOM API to append them together and add them to the web component's shadow DOM.
Access the templates contents, combine them together, create and import a new template, and then clone it as needed.
After much adversity I was able to successfully implement #1 but not #2 and that is motivation for my question. #2 is more appealing to me because it is easier for me to merge templates once rather than merging their resulting stamped instances and this approach seems to be the only way I can reuse nested templates like dom-repeat.
My main obstacle is that once Polymer or perhaps it's polyfill is loaded the templates become opaque and can only be utilized by Polymer templatize functionality. For instance, this code works fine without any Polymer imports:
<template>
<div>Template Contents</div>
</template>
<div>
Template Test
</div>
<script>
let template = document.querySelector("template");
let clone = document.importNode(template.content,true);
document.querySelector("div").appendChild(clone);
</script>
Outside of Polymer the template.content DOMFragment has children and innerHTML is set. However once Polymer is used the template.content has no children and the innerHTML is empty. This prevents me from using the DOM API to create a new template that blends the available templates together, i.e.
let newTemplate = document.createElement("template");
newTemplate.content = ... // combine #labelView > template.content with #nodeView.content
let nodeView = document.importNode(newTemplate.content,true);
nodeView.tree=...
Perhaps by design importing templates using the standard HTML mechanism didn't work for me. Is there another way to dynamically create/merge templates at runtime with Polymer? Again my main motivation is that I would like to re-use the dom-if and dom-repeat web components nested in a template without reimplementing all of their functionality.