when array item is removed and another one is added in one splice on model array, paper-tabs just removes removed item from DOM without adding a new one.
Please, take a look:
<!doctype html>
<html>
<head>
<title>paper-tabs-splicing-problem</title>
<meta name="description" content="When array item is removed and another one is added in one splice on model array, paper-tabs just removes removed item from DOM without adding a new one.">
<script src="https://rawgit.com/EdVaIl/polymer/master/dist/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="https://rawgit.com/EdVaIl/polymer/master/dist/bower_components/paper-tabs/paper-tabs.html">
</head>
<body>
<template is="dom-bind" id="app">
<template is="dom-repeat" items="[[items]]">
<div>[[item]]</div>
</template>
<paper-tabs scrollable>
<template is="dom-repeat" items="[[items]]">
<paper-tab>[[item]]</paper-tab>
</template>
</paper-tabs>
</template>
<script>
(function(document) {
'use strict';
var app = document.querySelector('#app');
app.addEventListener('dom-change', function() {
app.items = ['square', 'circle', 'pillow', 'triangle'];
});
window.addEventListener('WebComponentsReady', function() {
app.splice('items', 2, 1, 'line');
});
})(document);
</script>
</body>
</html>
You probably need to use the Polymer Array Mutation methods. See polymer array mutation docs
Related
Consider the following JSON:
{"EMD-4091":["EMD-4084","EMD-4090"]}
which is the result of a fictitious iron-ajax call as follows:
<iron-ajax
auto
url="http://me.com/get/EMD-4091"
handle-as="json"
last-response="{{my_data}}">
</iron-ajax>
Suppose I need to refer to the inner array, say, in a dom-repeat: how would I refer to 'EMD-4091' in a data binding? e.g.
<template is="dom-repeat" items="{{my_data????}}> <!-- what should this be?-->
<p>{{item}}</p>
</template>
If the data wasn't hyphenated this is a trivial task. The hyphen is the challenge I'm facing.
P
The data binding can still parse the hyphenated key without a problem, so your binding would be:
items="{{my_data.EMD-4091}}"
HTMLImports.whenReady(() => {
"use strict";
Polymer({
is: 'x-foo',
properties : {
my_data: {
type: Array,
value: () => ({"EMD-4091":["EMD-4084","EMD-4090"]})
}
}
});
});
<head>
<base href="https://polygit.org/polymer+1.7.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<template is="dom-repeat" items="[[my_data.EMD-4091]]">
<div>[[item]]</div>
</template>
</template>
</dom-module>
</body>
codepen
The below code does not show in the browser. This works in Polymer 0.5. Is there code difference as I am using 1.0?:
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="my-name">
<template>
<h1> Hello {{name}}</h1>
</template>
<script>
Polymer('my-name', {
ready: function() {
this.name = "Brown";
}
});
</script>
</polymer-element>
Basically you need to rewrite your element based on the new requirements. You can easily follow it in the migration guide, registration element section.
You should rewrite it like following:
<dom-module id="my-name">
<template>
<!--Keep in mind in polymer 1.0 you can't have whitespaces in bound tags-->
<h1>Hello <span>{{name}}</span></h1>
</template>
<script>
Polymer({
is: "my-name",
ready: function () {
this.name = "Brown";
}
});
</script>
</dom-module>
I did a Plunker where you can reproduce it.
<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="my-name">
<style>
/*your styles go here*/
<style>
<template>
<!-- Things to show in element view -->
<h1> Hello <span>{{name}}</span></h1>
</template>
<dom-module>
<script>
// Your script goes here
Polymer({
is: 'my-name',
properties: {
name: {
type: String,
value: 'Brown'
}
}
});
</script>
There are many differences when migrating from Polymer 0.5 to Polymer 1.0 +. They changed the old polymer-element to dom-module and name attribute to id. The constructor is also changed as i shown in the example. Read https://www.polymer-project.org/1.0/docs/migration.html to get more info on migrating.
polymer 1.0 changes <polymer-element name="my-name"> to <dom-module id="my-name">.
I think you should follow the documentation of polymer 1.0
Polymer 1.0 documentation
I've created a test polymer element where in I was figuring out how to use use arrays in templates. My code does not work and the documentation for 1.0 doesn't really talk much about how to use repeat in template tags.
my element:
<!-- Imports polymer -->
<link rel="import" href="polymer/polymer.html">
<!-- Defines element markup -->
<dom-module id="my-element" >
<template>
<style>
my-element
</style>
<h2>{{data}}</h2>
<ul>
<template repeat={{column in columns}} bind>
<li>{{column}}</li>
</template>
</ul>
</template>
</dom-module>
<!-- Registers custom element -->
<script>
Polymer({
is: 'my-element',
// Fires when an instance of the element is created
created: function() {
},
// Fires when the local DOM has been fully prepared
ready: function() {},
// Fires when the element was inserted into the document
attached: function() {},
// Fires when the element was removed from the document
detached: function() {},
// Fires when an attribute was added, removed, or updated
attributeChanged: function(name, type) {
alert("changed");
},
properties:{
data :String,
columns:Array
}
});
</script>
and the index.html page where I'm using the element:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title><my-repo></title>
<!-- Imports polyfill -->
<script src="webcomponents-lite.min.js"></script>
<!-- Imports
custom element -->
<link rel="import" href="my-element.html">
<!-- Runs custom element -->
<my-element users = '{{[1,2,3,4]}}' data="This is a polymer table"></my-element>
Please let me know what's wrong with my code!!
You have to use
<template is="dom-repeat" items="{{users}}">
<li>{{item}}</li>
</template>
And in main file:
<my-element users="[1,2,3,4]" data="This is a polymer table"></my-element>
You can search Youtube for Polycast, a series by Google Developers where they're talking about Polymer for beginners and showing cool tricks.
Polymer 1.0 does not allow expressions in data binding. The problem is in:
<my-element users = '{{[1,2,3,4]}}' ...>
You need to replace {{[1,2,3,4]}} with a property. Something like this:
<template is="dom-bind">
<my-element users = '{{myarray}}' data="This is a polymer table"></my-element>
</template>
<script>
(function() {
var template = document.querySelector('template[is="dom-bind"]');
template.myarray = [1,2,3,4];
})();
</script>
Using the repeat and in expression it is trivial to iterate over arrays, but swapping
this.data = ["foo","bar"];
to
this.data = {foo:"football",bar:"barfly"}
fails to iterate over the object. I have seen examples of using Object.key in order to get each value, but the index returned is 0,1 instead of "foo" "bar".
While this simple example doesn't use 2 way binding, I would like to keep support for it, in case I need it in the future.
http://jsbin.com/copogeyome/1/
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Polymer</title>
<script src="http://www.polymer-project.org/components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
</head>
<body>
<polymer-element name="an-consumer" attributes="data" noscript>
<template>testing {{data.foo}}<br>
<template id="foo">f {{}}<br></template>
<template id="bar">b {{}}<br></template>
<template id="0">0 {{}}<br></template>
<template id="1">1 {{}}<br></template>
<template id="2">2 {{}}<br></template>
{
<template repeat="{{obj,index in data}}" bind="{{data}}">
( {{index}} - {{obj}} ) = <template ref="{{index}}" bind="{{obj}}"></template>
</template>
}
</template>
</polymer-element>
<polymer-element name="an-supplier" attributes="data">
<template></template>
<script>
Polymer({
ready: function(){
this.data = ["foo","bar"];
//this.data = {foo:"football",bar:"barfly"}
}
});
</script>
</polymer-element>
<polymer-element name = "an-root" noscript>
<template>
<an-supplier data="{{stuff}}"></an-supplier>
<an-consumer data="{{stuff}}"></an-consumer>
</template>
</polymer-element>
<an-root>
</an-root>
</body>
</html>
While there is [yet] no built-in ability to iterate over object, you might easily achieve this functionality with filter:
<template repeat="{{key in data | getKeys}}">
<span>Key: {{key}}</span>
<span>Value: {{data[key]}}</span>
</template>
<script>
Polymer({
ready: function(){
// this.data = ["foo","bar"];
this.data = {foo:"football",bar:"barfly"}
}
// filter function to use in looping objects
getKeys : function(o) {
return Object.keys(o);
}
});
</script>
Whether you have additional questions, please, don’t hesitate to ask.
Live: http://jsbin.com/munehitogu/1/edit
Would it be possible to import templates from another file? I'm able to import javascript and stylesheet, but cannot figure out how to import html templates.
For example:
I defined various content-item templates in templates.html
<template id="hello>Hello {{ li.name }}</template>
<template id="hey">Hey!</template>
And then, I would like to re-use the templates in list.html
<link rel="import" href="templates.html">
<polymer-element name="list" attributes="type,data">
<template>
<template repeat="{{ li in items_in_data }}">
<template bind ref="hey"></template>
<template bind ref="{{ type }}"></template>
</template>
</template>
</polymer-element>
Finally, in app.html
<list data="items.json" type="hello"></list>
If I put the contents inside templates.html into list.html, it works fine. However, it does not seem to load or reference when using <link rel="import">. Any ideas?
Partial solution: The below works in chrome but not polyfill browsers (e.g. firefox). Need to look through polyfill code to figure out how to handle links in a file already linked.
The issue is that the content of the import is not inserted into the document but is just made available for use. See HTML5 Rocks imports - using content for more details. You can find all of the templates in the linked file and insert them into your polymer element's document fragment:
var importDoc = document.currentScript.ownerDocument;
var link = importDoc.querySelector('.myimports');
var templates = link.import.querySelectorAll('template');
for (var i=0;i<templates.length;i++) {
importDoc.head.appendChild(templates[i]);
}
Example
demo-templates.html
<template id="hello">Hello World!</template>
<template id="goodbye">See you tomorrow</template>
demo-importTemplates-list.html
<link class="myimports" rel="import" href="demo-templates.html">
<polymer-element name="demo-importTemplates-list">
<template>
<template repeat="{{ li in data }}">
<h1>{{li}}</h1>
<template bind ref="hello"></template> -- <template bind ref="goodbye"></template>
</template>
</template>
<script>
Polymer({
data: ['first','second','third']
});
// http://www.html5rocks.com/en/tutorials/webcomponents/imports/#usingcontent
// http://www.html5rocks.com/en/tutorials/webcomponents/imports/#include-templates
var importDoc = document.currentScript.ownerDocument;
var link = importDoc.querySelector('.myimports');
var templates = link.import.querySelectorAll('template');
for (var i=0;i<templates.length;i++) {
importDoc.head.appendChild(templates[i]);
}
</script>
</polymer-element>
index.html
<html lang="en">
<head>
<script src="../../webcomponents/bower_components/webcomponentsjs/webcomponents.min.js"></script>
<link rel="import" href="../../webcomponents/bower_components/polymer/polymer.html">
<link rel="import" href="demo-importTemplates-list.html">
<title>demo-importTemplates</title>
</head>
<body>
<demo-importTemplates-list type="hello"></demo-importTemplates-list>
</body>
</html>