In this step we are going to create a more complex Polymer element, a custom beer-list
.
This element will use a JavaScript array as model and automatically generate a beer-list-item
for each beer in the array.
We begin by creating a new file for the element, elements/beer-list.html
. Inside it we put a basic Polymer element definition:
<!-- Our beer-list will generate `beer-list-item` elements, so we import it -->
<link rel="import" href="./beer-list-item.html">
<dom-module id="beer-list">
<template>
<!-- local DOM for your element -->
<style>
/* CSS rules for your element */
</style>
</template>
<script>
// element registration
Polymer({
is: "beer-list",
// add properties and methods on the element's prototype
properties: {
}
});
</script>
</dom-module>
We are going to model our (ever growing) beer collection as a JavaScript array in our beer-list
element.
We will use the element's ready
function, a function that is called when the element has been loaded and instantiated, and that is often used to initialize variables.
<script>
// element registration
Polymer({
is: "beer-list",
// add properties and methods on the element's prototype
properties: {
beers: {
type: Array,
// When initializing a property to an object or array value, use a function to ensure that each element
// gets its own copy of the value, rather than having an object or array shared across all instances of the element
value: function() { return []; }
}
},
ready: function() {
this.beers = [
{
alcohol: 8.5,
name: "Affligem Tripel",
description: "The king of the abbey beers. It is amber-gold and pours with a deep head and original aroma, delivering a complex, full bodied flavour. Pure enjoyment! Secondary fermentation in the bottle."
},
{
alcohol: 9.2,
name: "Rochefort 8",
description: "A dry but rich flavoured beer with complex fruity and spicy flavours."
},
{
alcohol: 7,
name: "Chimay Rouge",
description: "This Trappist beer possesses a beautiful coppery colour that makes it particularly attractive. Topped with a creamy head, it gives off a slight fruity apricot smell from the fermentation. The aroma felt in the mouth is a balance confirming the fruit nuances revealed to the sense of smell. This traditional Belgian beer is best savoured at cellar temperature "
}
];
}
});
</script>
So now we have a beers
property in our element, that can be access in the JS side using this.beers
and in the dom-model
side using {{beers}}
.
As you can see, for each beer we have the name
and description
properties that beer-list-item
needs, and also added an alcohol
property that our element isn't capable to use yet.
A reasonable thing to do for our beer-list
would be to spawn a beer-list-element
for each beer in the beers
array. How can we do that? By using Polymer's data binding helper element, concretely a template repeater (dom-repeat
):
<dom-module id="beer-list">
<template>
<style>
/* CSS rules for your element */
</style>
<div class="beers">
<template is="dom-repeat" items="{{beers}}">
<beer-list-item name="{{item.name}}" description="{{item.description}}">
</beer-list-item>
</template>
</div>
</template>
</dom-module>
The template repeater is a specialized template that binds to an array. It creates one instance of the template’s contents for each item in the array. It adds two properties to the binding scope for each instance:
item
: The array item used to create this instanceindex
: The index of item in the array
For more information about the template repeater, see the Polymer documentation.
In the index.html
file we aren't going to use directly beer-list-item
elements anymore, but a simple beer-list
.
Let's replace the import of beer-list-item
by an import of beer-list
:
<!-- Import `beer-list` element -->
<link rel="import" href="./elements/beer-list.html">
And use it in the body:
<div class="container">
<beer-list></beer-list>
</div>
In the element's dom-model
you have access to the beers variable, you can then get it's size and show it after the beers:
<div>Number of beers in list: {{beers.length}}</div>
Note: unlike precedent Polymer versions, Polymer 1.0 required the double curly-brake syntax ({{}}
) to be used as the only element inside a DOM node. So the precedent line needed to be rewritten as <div>Number of beers in list: <span>{{beers.length}}</span></div>
. This restriction was lifted on Polymer 1.2.
Create a repeater in beer-list
that constructs a simple table:
<table>
<tr><th>Row number</th></tr>
<template is="dom-repeat" items="[0, 1, 2, 3, 4, 5, 6, 7]">
<tr><td>{{item}}</td></tr>
</template>
</table>
Extra points: try and make an 8x8 table using an additional dom-repeat
.
Note: To access properties from nested dom-repeat
templates, use the as
attribute to assign a different name for the item property. Use the index-as
attribute to assign a different name for the index
property.
You now have a web application using Polymer web components. Now, let's go to step-04 to learn how to add full text search to the app.