I am trying to create common web components that display collections of JSON objects, such as tree view and multiple list view (moving items between two lists). I would like to copy the template used by the iron list, where the template containing the view of an individual element is passed to the component for reuse.
For example, 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> </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 use:
<intworkspace-tree tree="{{testTree}}"> <template><paper-item-body>[[node.name]]</paper-item-body> </template> </intworkspace-tree>
I would like to display an array of the JSON tree in a hierarchy that combines the web component template along with the template provided through the slot to render opaque JSON objects. So far, I have defined two methods for combining patterns:
Use the Polymer.Templatize.templatize API to load templates, create / stamp new instances, and use the DOM API to add them together and add them to the web component DOM.
Access to the contents of the templates, combining them, creating and importing a new template, and then cloning as necessary.
After many troubles, I was able to successfully implement # 1, but not # 2, and this is the motivation for my question. # 2 is more attractive to me because itβs easier for me to combine patterns once, rather than combining their resulting stamped instances, and this approach seems to be the only way to reuse nested patterns such as dom-repeat.
My main obstacle is that after loading Polymer or, possibly, loading polyfill, the templates become opaque and can only be used using the templatize function from Polymer. For example, this code works fine without importing polymer:
<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, template.content DOMFragment has children and innerHTML. However, as soon as Polymer is used, template.content has no children, and innerHTML is empty. This prevents me from using the DOM API to create a new template that combines 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 did not work for me. Is there any other way to dynamically create / merge templates while working with Polymer? Again, my main motivation is that I would like to reuse the dom-if and dom-repeat web components nested in the template without overriding all their functionality.