app-router not working imperatively way - polymer

I have this Polymer custom element:
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/core-animated-pages/core-animated-pages.html">
<link rel="import" href="../../../bower_components/app-router/app-router.html">
<polymer-element name="custom-pages" attributes="selected">
<template>
<link rel="stylesheet" href="custom-pages.css">
<app-router id="router" bindRouter core-animated-pages transitions="cross-fade-all" trailingSlash="ignore">
<template repeat="{{page in pages}}">
<app-router path="{{page.path}}" import="{{page.url}}"></app-router>
</template>
</app-router>
</template>
<script>
(function() {
Polymer({
selected: 0,
pages: [{
path: "/home",
url: '../custom-home/custom-home.html'
}, {
path: "/about",
url: '../custom-about/custom-about.html'
}],
selectedChanged: function(oldValue, newValue) {
router = this.$.router;
router.go(this.pages[newValue].path);
}
});
})();
</script>
</polymer-element>
Elements custom-home and custom-about should be lazy loaded when "selected" change, but not is happening (no page is displayed).

You have a syntax error in your template definition, nested tags are to be app-route rather than app-routeR:
<app-router id="router" ...>
<template repeat="{{page in pages}}">
<!-- ⇓ superfluous r, nested are app-route -->
<app-router path="{{page.path}}" import="{{page.url}}"></app-router>
<!-- SHOULD BE: -->
<app-route path="{{page.path}}" import="{{page.url}}"></app-route>
</template>
</app-router>
Currently you have created a bundle of empty routers.
Plus, the documentation says:
If you use go(path, options) you should also set the mode to hash or pushstate on the router.
I am not sure if this affects your case, since you do not seem to pass options.
Hope it helps.

Related

Polymer 1.x: accessing element within dom-if

Here is my JSBin
Click on the "First Name: James" text.
I have an input element within dom-if. In an event, I am making dom-if to pass and so the element will come into existence but I cannot access the input element immediately after making the dom-if condition pass.
May be I need to know when the dom-if is actually evaluated and why the element does not exist even if the condition has become true.
<!doctype html>
<head>
<meta charset="utf-8">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link href="iron-form/iron-form.html" rel="import">
<link href="paper-input/paper-input.html" rel="import">
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<template is="dom-if" if="{{!editMode}}">
<span id="name" on-tap="_makeEditable">{{name}}: {{value}}</div>
</template>
<template is="dom-if" if="{{editMode}}">
<paper-input id="input" label="{{name}}" value="{{value}}"></paper-input>
</template>
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
editMode: {
type: Boolean,
value: false
},
name: {
type:String,
value:"First Name"
},
value: {
type:String,
value:"James"
}
},
_makeEditable: function() {
this.editMode = true;
//how to find the input element here
//this.$$('#input').querySelector("input").focus();
//this.$.input.querySelector("input").focus();
}
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>
This is because setting this.editMode to true does not update the DOM instantaneously.
You should be running your selector asynchronously, so that Polymer has some time to update the DOM, such as:
this.async(function() {
this.$$('#input').focus();
})
Fiddle here.

Looking for different pattern match in app-route

I am using the Polymer CLI to create an app. I am utilizing Encapsulated Routing with Elements and Step 1. Get set up am trying to match the following patterns:
/analyze/:p1
/analyze/:p1/:p2
/analyze/:p1/:p2/:p3
That routes to 3 different web components.
For your <app-route> element, set the following attributes:
pattern = your desired route pattern
data = property binding to contain the parsed paths
In your case:
<app-route
pattern="/analyze/:p1/:p2/:p3"
data="{{routeData}}">
</app-route>
{{routeData}} will contain:
{
p1: 'a',
p2: 'b',
p3: 'c'
}
<head>
<base href="https://polygit.org/polymer+:master/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="app-route/app-route.html">
<link rel="import" href="paper-input/paper-input.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<app-route
route="{{route}}"
pattern="/analyze/:p1/:p2/:p3"
data="{{routeData}}"
tail="{{tail}}">
</app-route>
</template>
<script>
Polymer({
is: 'x-foo',
ready: function() {
this.route = {path: "/analyze/a/b/c/d/e/f"};
console.log('p1', this.routeData.p1);
console.log('p2', this.routeData.p2);
console.log('p3', this.routeData.p3);
console.log('tail', this.tail.path);
}
});
</script>
</dom-module>
</body>
jsbin

Polymer: Passing properties to child element doesn't work

I'm trying to output data from a custom Polymer component <data-component> in an <iron-list> but nothing is shown when I open the page. It works when I pass an array of objects directly to the iron-list like <iron-list items='[{"name": "test1"}, {"name":"test2"}]' >
What am I doing wrong here and is the <template is="dom-bind" id="t"> mandatory?
index.html
<html>
<head>
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../data-component.html">
<link rel="import" href="../../iron-list/iron-list.html">
</head>
<body unresolved>
<template is="dom-bind" id="t">
<data-component>
<!--<iron-list items='[{"name": "test1"}, {"name":"test2"}]' > WORKS -->
<iron-list items="{{data}}" >
<template>
<div>
Name: <span>{{item.name}}</span>
</div>
</template>
</iron-list>
</data-component>
</template>
</body>
</html>
data-component.html
<link rel="import" href="../polymer/polymer.html">
<dom-module id="data-component">
<template>
<content></content>
</template>
</dom-module>
<script>
window.coolData = [
{"name": "Bob"},
{"name": "Tim"},
{"name": "Mike"}
];
Polymer({
is: 'data-component',
properties: {
data: {
value: window.coolData
}
}
});
</script>
I'm going to suggest an alternative answer to what I have already posted. If you want your data-component to always contain the iron-list then you can use this version here. However, if the content of the data-component should be more flexible use my other answer.
If you move the iron-list inside the data-component you can remove the dom-bind in your index.html.
data-component.html
<link rel="import" href="../polymer/polymer.html">
<dom-module id="data-component">
<template>
<iron-list items="{{data}}" >
<template>
<div>
Name: <span>{{item.name}}</span>
</div>
</template>
</iron-list>
</template>
</dom-module>
<script>
window.coolData = [
{"name": "Bob"},
{"name": "Tim"},
{"name": "Mike"}
];
Polymer({
is: 'data-component',
properties: {
data: {
type: Array,
value: window.coolData
}
}
});
</script>
index.html
<body unresolved>
<data-component></data-component>
</body>
You also have to add a data-binding to your data-component. Otherwise, the system does not know that data (in your iron-list) should refer to the data property in your custom element.
<data-component data="{{data}}">
<iron-list items="{{data}}" >
...
</iron-list>
</data-component>
The dom-bind is necessary if you want to have data-binding outside of a Polymer element, which seems to be the case here.
You should also make sure that the data property is configured to notify changes and that its type is set to Array.
Polymer({
is: 'data-component',
properties: {
data: {
type: Array,
value: window.coolData,
notify: true
}
}
});

template repeat in polymer 1.0

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>

How to use apps-global with polymer's sampler-scaffold?

I am using sample-scaffold from https://github.com/Polymer/sampler-scaffold and define some globale variables using app-globals as described in https://www.polymer-project.org/docs/polymer/polymer.html#global
like
<app-globals myvar="value"></app-globals>
<sampler-scaffold>
<core-item label="Page 1" url="page1.html"></core-item>
</sampler-scaffold>
page1.html contains also the app-globals without values.
<app-globals id="globals"></app-globals>
However, the globals element does not contain any values. Is there a way to define globals across iframes using app-globals?
What about using the Polymer Element extensions? and inheritance to keep the interface of the app-globals object static? My Plunker: http://embed.plnkr.co/uDPTVP/preview
app-config.html
<!-- per https://www.polymer-project.org/docs/polymer/polymer.html#extending-other-elements -->
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
<link rel="import" href="app-globals.html">
<polymer-element name="app-config" extends="app-globals">
<script>
Polymer({
ready: function () {
this.super();
this.values.GloabalSettingsVal1 = "GDG FTW"
}
});
</script>
</polymer-element>