18 Temmuz 2018 Çarşamba

Injecting Template Example with Data Binding in Polymer 3.0

In the world of Web Components, it is always easy for a developer to set a property or attribute of a component but it is a little bit complicated to use a component inside another one with data binding for each.

If you are using Polymer Framework, the most obvious example is iron-list component. This component requires a <template> between its tags and each component in this template has its own data. An example is shown below:

<iron-list items="[[items]]">
  <template>
    <div> [[item.myProp]] </div>
  </template>
</iron-list>

Until Polymer 3.0, this was done with templatizing and slotting. I do not want to go into details but before Polymer 3.0, it was pretty much like below:

  • Polymer.Templatizer behavior should be added 
  • Main template of the component should be templatized : this.templatize(template)
  • Clone the item inside template tags with 
    • var clone = this.stamp()
  • Optionally, bind data you want inside this clone 
    • var clone = this.stamp({item:{"myProp":"Test"}})
  • And finally put your cloned element with data inside any HTML element
    • Polymer.dom(this.$.myDiv).appendChild(clone.root);
  • And that is it for < Polymer 3.0...

Things are a little different in Polymer 3.0. Again you should use the power of Templatize class but honestly it was very difficult to find a proper documentation or example to do this. So I want to share my experiences with you and I will do this with a real example. What I did is to create a simple custom-card component which has two properties firstText and secondText. This component is a simple card view which renders two given text with different colors. This is the easy one. My other component is a custom-list component which loops the first component in it with data binding by template injection.

<custom-list id="myList"> 
   <template>
      <custom-card first-text="Book Name: [[item.title]]" second-text="Author: [[item.author]]" />
   </template>
</custom-list>

Let's continue step by step:

1. You should import templatize class
import { templatize } from 'node_modules/@polymer/polymer/lib/utils/templatize.js';

2. Get the template object between tags of custom-list
var template = this.querySelector('template');

3. Call templatize method to get a TemplateClass object in order to do stamping
var TemplateClass = templatize(template);

4. Items property is an array contains JSON objects like {title:"MyItem", author:"MyAuthor"}. In a for loop, these object should be injected into each <custom-card> object as "item" property:
var instance = new TemplateClass( { item : this.items[i] } );
this.shadowRoot.appendChild(instance.root);

This simple code will let you iterate through each of your data in "items" property, create <custom-card> clones and inject this data into these clones. There is full working code available below. Hope this code block helps other developers who is struggling the same templatizing work in Polymer 3.0  

Code:


( polymer, polymer 3.0, template, templatizing, slot, inject, data bind, web components, stamp )