2017-05-22 13 views
5

मैं सामान्य वेब घटकों को बनाने का प्रयास कर रहा हूं जो JSON ऑब्जेक्ट संग्रह, जैसे पेड़ दृश्य और बहु-सूची दृश्य (दो सूचियों के बीच चलती वस्तुओं) प्रस्तुत करते हैं। मैं लोहे की सूची द्वारा उपयोग किए गए पैटर्न की प्रतिलिपि बनाना चाहता हूं जहां व्यक्तिगत आइटम प्रस्तुति वाला टेम्पलेट पुन: उपयोग के लिए घटक में पारित किया जाता है।पॉलिमर 2 गतिशील रूप से विलय टेम्पलेट्स

उदाहरण के लिए

, इस वेब घटक टेम्पलेट दिया:

<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> 
 
\t ... 
 
    </dom-module>

और इस प्रयोग:

<intworkspace-tree tree="{{testTree}}"> 
 
     <template><paper-item-body>[[node.name]]</paper-item-body> </template> 
 
    </intworkspace-tree> 
 
मैं में JSON पेड़ सरणी प्रस्तुत करना चाहते हैं एक पदानुक्रम जो वेब घटक के टेम्पलेट को जोड़ता है ओपेक JSON ऑब्जेक्ट्स को प्रस्तुत करने के लिए स्लॉट के माध्यम से प्रदान किए गए टेम्पलेट के साथ एनजी।

  1. , टेम्पलेट्स लोड करने के लिए Polymer.Templatize.templatize एपीआई का उपयोग/डाक टिकट नया उदाहरण बना, और उन्हें एक साथ संलग्न करें और उन्हें जोड़ने के लिए डोम एपीआई का उपयोग: अब तक मैं टेम्पलेट्स के संयोजन के दो तरीके की पहचान की है वेब घटक की छाया डोम के लिए।

  2. टेम्पलेट सामग्री तक पहुंचें, उन्हें एक साथ मिलाएं, एक नया टेम्पलेट बनाएं और आयात करें, और फिर आवश्यकतानुसार इसे क्लोन करें।

बहुत परेशानी के बाद मैं # 1 को सफलतापूर्वक कार्यान्वित करने में सक्षम था लेकिन # 2 नहीं और यह मेरे प्रश्न के लिए प्रेरणा है। # 2 मेरे लिए अधिक आकर्षक है क्योंकि मेरे परिणामस्वरूप मुद्रित उदाहरणों को विलय करने के बजाए टेम्पलेट्स को एक बार मर्ज करना मेरे लिए आसान है और यह दृष्टिकोण एकमात्र तरीका है जो मैं नेस्टेड टेम्पलेट्स जैसे डोम-दोहराना का पुन: उपयोग कर सकता हूं।

मेरा मुख्य बाधा यह है कि एक बार पॉलिमर या शायद इसकी पॉलीफिल लोड हो जाती है तो टेम्पलेट अपारदर्शी हो जाते हैं और केवल पॉलिमर टेम्पलेटैट कार्यक्षमता द्वारा इसका उपयोग किया जा सकता है। उदाहरण के लिए, इस कोड को किसी भी पॉलिमर के आयात के बिना ठीक काम करता है:

<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>

पॉलिमर के बाहर template.content DOMFragment बच्चे हैं और innerHTML निर्धारित है। हालांकि एक बार पॉलिमर का उपयोग किया जाता है टेम्पलेट। कॉन्टेंट में कोई बच्चा नहीं है और आंतरिक HTML खाली है। यह मैं हूँ कि एक साथ मिश्रण उपलब्ध टेम्पलेट एक नया खाका बनाने के लिए डोम एपीआई का उपयोग करने से रोकता है, यानी

let newTemplate = document.createElement("template"); 
 
newTemplate.content = ... // combine #labelView > template.content with #nodeView.content 
 
let nodeView = document.importNode(newTemplate.content,true); 
 
nodeView.tree=...

शायद मानक HTML प्रणाली का उपयोग करके मेरे लिए काम नहीं किया टेम्पलेट्स डिजाइन आयात करके

। पॉलिमर के साथ रनटाइम पर टेम्पलेट्स को गतिशील रूप से बनाने/मर्ज करने का कोई और तरीका है? फिर मेरी मुख्य प्रेरणा यह है कि मैं अपने सभी कार्यक्षमताओं को दोबारा लागू किए बिना टेम्पलेट में घोंसला वाले डोम-आई और डोम-दोहराने वाले वेब घटकों का पुन: उपयोग करना चाहता हूं।

उत्तर

4

अतिरिक्त शोध के बाद मैंने पॉलिमर 2 की तीन विशेषताएं खोज लीं।0 जिसने मुझे एक संतोषजनक समाधान तैयार करने में सक्षम बनाया:

  1. जब भी पॉलिमर डोम टेम्पलेट्स को संसाधित करता है तो यह डिफ़ॉल्ट रूप से उन्हें याद करता है। यह टेम्पलेट कैशिंग व्यय क्लोनिंग परिचालन को रोकता है और टेम्पलेट बाध्यकारी को सरल बनाता है। पॉलिमर 2.0 डोम टेम्पलेटिंग प्रलेखन बताता है कि टेम्पलेट में संरक्षित-सामग्री विशेषता को टेम्पलेट में जोड़ा जा सकता है ताकि टेम्पलेट को मूल डीओएम संचालन का उपयोग करके टेम्पलेट को छेड़छाड़ की अनुमति दी जा सके।

  2. डोम टेम्पलेटिंग दस्तावेज़ कस्टम तत्व के कच्चे टेम्पलेट को प्राप्त करने के कई तरीकों का भी वर्णन करता है। एक विकल्प तत्व की स्थिर टेम्पलेट() विधि को कॉल करना है और दूसरा विकल्प Polymer.DomModule.import() फ़ंक्शन का उपयोग करना है। यह दूसरी विधि मेरे लिए ब्याज की थी क्योंकि यह डिफ़ॉल्ट मॉड्यूल टेम्पलेट से परे कई टेम्पलेट प्रबंधित करने की अनुमति देती है।

  3. पॉलिमर। टेम्पलेटस्टैम्प एपीआई क्लास में एक आंतरिक _स्टैम्प टेम्पलेट() फ़ंक्शन है जिसका उपयोग कस्टम तत्व के डोम में टेम्पलेट को मुद्रित करने के लिए किया जाता है। मैं अच्छी तरह से प्रलेखित Polymer.Templatize.templatize() फ़ंक्शन का उपयोग करना पसंद करता था लेकिन यह टेम्पलेट पर गुणों और विधियों की तलाश करता है जो मेरे मामले में परिभाषित व्यवहार के साथ एक कस्टम तत्व नहीं था।

इन तीन सुविधाओं लाना एक साथ मैं utlizing नेस्टेड डोम-आईएफएस और एक डोम-दोहराता के रूप में मैं वांछित एक गतिशील पुन: प्रयोज्य मर्ज किए गए टेम्पलेट तैयार करने में सक्षम था।

घटक::

<link rel="import" href="../polymer/polymer-element.html"> 
 
<link rel="import" href="../iron-collapse/iron-collapse.html"> 
 
<link rel="import" href="../paper-item/paper-icon-item.html"> 
 
<link rel="import" href="../paper-item/paper-item-body.html"> 
 
<link rel="import" href="../iron-flex-layout/iron-flex-layout-classes.html"> 
 
<link rel="import" href="../iron-icons/iron-icons.html"> 
 
<link rel="import" href="../iron-icon/iron-icon.html"> 
 

 

 
<dom-module id="intworkspace-tree"> 
 
    <template> 
 
    <!-- style includes don't work in stamped template, only in the shadowRoot --> 
 
    <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> 
 

 
    <template id="nodeView"> 
 

 
    
 

 
    <template is="dom-repeat" items="{{tree}}" as="node" index-as="n"> 
 
     <div class="layout vertical"> 
 
      <!--<div>index: [[n]]</div> 
 
      <div>name: [[node.name]]</div>--> 
 
      <paper-icon-item on-tap="nodeSelected"> 
 
      <template is="dom-if" if="[[hasNodes(node)]]"> 
 
       <iron-icon icon="expand-more" slot="item-icon" hidden$="[[!hasNodes(node)]]"></iron-icon> 
 
      </template> 
 
      <!-- label goes here--> 
 
      </paper-icon-item> 
 
      <template is="dom-if" if="[[hasNodes(node)]]"> 
 
      <iron-collapse class="node" opened> 
 
       <intworkspace-tree tree="[[node.nodes]]" node-template="[[nodeTemplate]]" embedded></intworkspace-tree> 
 
      </iron-collapse> 
 
      </template> 
 
     </div> 
 
    </template> 
 
    </template> 
 

 
    <script> 
 
    class IntTree extends Polymer.TemplateStamp(Polymer.Element) { 
 

 
     static get is() { 
 
     return 'intworkspace-tree'; 
 
     } 
 

 
     static get properties() { 
 
     return { 
 
      tree: { 
 
      type: Array, 
 
      value: [] 
 
      }, 
 
      nodeTemplate: { 
 
      type: Object, 
 
      } 
 
     }; 
 
     } 
 

 
     ready() { 
 
     super.ready(); 
 
     if (!this.hasAttribute("embedded")) { 
 
      let labelTemplate = this.$.labelView.assignedNodes().find((e) => { 
 
      return e instanceof HTMLTemplateElement; 
 
      }); 
 
      let nodeTemplate = document.importNode(Polymer.DomModule.import(IntTree.is, "#nodeView"), true); 
 
      let repeatTemplate = nodeTemplate.content.querySelector("template[is='dom-repeat']"); 
 
      let iconItem = repeatTemplate.content.querySelector('paper-icon-item'); 
 
      iconItem.appendChild(labelTemplate.content); 
 
      this.nodeTemplate = nodeTemplate; 
 
     } 
 
     let nodeInstance = this._stampTemplate(this.nodeTemplate); 
 
     this.shadowRoot.appendChild(nodeInstance); 
 
     } 
 

 
     hasNodes(node) { 
 
     return node.nodes != null && node.nodes.length > 0; 
 
     } 
 

 
     nodeSelected(e) { 
 
     let collapse = e.currentTarget.parentNode.querySelector("iron-collapse"); 
 
     let nodeIcon = e.currentTarget.parentNode.querySelector("iron-icon"); 
 
     if (collapse && nodeIcon) { 
 
      collapse.toggle(); 
 
      if (collapse.opened) { 
 
      nodeIcon.icon = "expand-more"; 
 
      } else { 
 
      nodeIcon.icon = "expand-less"; 
 
      } 
 
     } 
 
     } 
 
    } 
 

 
    window.customElements.define(IntTree.is, IntTree); 
 
    </script> 
 
</dom-module>

उपयोग:

<intworkspace-tree tree="{{testTree}}"> 
 
     <template preserve-content><paper-item-body>[[node.name]]</paper-item-body></template> 
 
    </intworkspace-tree>

0

यहाँ कार्यात्मक परिणाम हैमैं यहां हारून के समाधान के लिए एक अवलोकन जोड़ता हूं क्योंकि मेरे पास कोई टिप्पणी जोड़ने के लिए पर्याप्त प्रतिष्ठा नहीं है।

नोट इस लाइन एक डबल आयात

let nodeTemplate = document.importNode(Polymer.DomModule.import(IntTree.is, "#nodeView"), true); 

है यह आवश्यक नहीं है। कुछ कारणों से क्रोम और सफारी काम करता है, लेकिन एफएफ में नहीं।

तो, पॉलिमर के साथ काम सिर्फ DomModule आयात का उपयोग करने के लिए पर्याप्त

let nodeTemplate = Polymer.DomModule.import(IntTree.is, '#nodeView'); 

आशा इस मदद करता है किसी को

है
संबंधित मुद्दे