Change auto-binding template from element using Polymer - polymer

<template is="dom-bind" id="app">
<div>{{title}}</div>
<my-element></my-element>
</template>
Can I inside my-element force the auto-bind template to redraw?
I can get the template, but changing it does not trigger a redraw:
var app = document.querySelector('#app');
app.title = 'Zaphod';

Your code should work, except setting the title needs to wait until polymer is ready (i.e. elements have been registered and are ready to be interacted with).
var app = document.querySelector('#app');
document.addEventListener("WebComponentsReady", function () {
app.title = 'Zaphod';
});

Related

What is the best practice to set variables on the app with new carbon-route element

In the polymer starter kit the whole app is wrapped in a template (id="app") as follows:
<body unresolved>
<span id="browser-sync-binding"></span>
<template is="dom-bind" id="app">
...
<!-- One of my custom elements -->
<position-el id="editElemID" position-id="[[params.posId]]"></position-el>
...
</template>
</body>
One of the ways I benefit from this style is that I can set some variables on the app when the route changes as follows:
page('/position/:posName/:posId/edit', function(data) {
app.route = 'positionEdit';
app.$.editElemID.edit = true;
app.params = data.params;
});
Can I set variables on the app level in a similar way using the new carbon-route element?
Sure, carbon-route exposes a data param with the captured :segments of the URL pattern. These are exposed for easy data binding and observing.

Polymer workflow and architecture

I'd like to ask you people about workflow with Polymer. I know that I should use my own elements or double check if element that I need isn't alredy published. It's really nice, I admit it. However the Polymer Starter Kit comes as single-page app. Is it the recommended approach for using Polymer? What about large pages that would need a lot of data to be loaded? Are there alternative approaches?
You don't need to have all your elements rendered at same time. They can be created on the fly only when needed, and can be destroyed as well.
To create your elements on the fly, you can use DOM Manipulation methods like:
var myElement = document.createElement("my-element");
this.$.container.appendChild(myElement);
myElement.myProperty = "anything";
To remove, just do this way:
var myElement = this.$.container.querySelector("my-element");
myElement.parentNode.removeChild(myElement);
If you need dynamic load a HTML Import, you can use this.importHref if your code is inside a polymer Element (and it should be).
this.importHref('myElement.html', function(e) {
// Create your element here
});
Putting things together...
Suppose you have a polymer element like that:
<dom-module id="my-app">
<template>
<div id="container"></div>
<paper-button on-click="_loadElement">Load Element</paper-button>
<paper-button on-click="_removeElement">Remove Element</paper-button>
</template>
</dom-module>
<script>
Polymer({
is: 'my-app',
_loadElement: function() {
this.importHref('myElement.html', function(e) {
var myElement = document.createElement("my-element");
this.$.container.appendChild(myElement);
myElement.myProperty = "anything";
});
},
_removeElement: function() {
var myElement = this.$.container.querySelector("my-element");
myElement.parentNode.removeChild(myElement);
}
});
</script>

Polymer error when template is auto binding

I'm trying to use core-list extension from polymer.
I used example from Google Developers from This YT Link
I add is="auto-binding" value to my template i go error:
Uncaught TypeError: Cannot set property 'data' of null
I'm also trying to set height: 100% to core-list , it's also not working , I got warning:
core-list must either be sized or be inside an overflow:auto div that is sized
Below I'm adding my code:
<link rel="import" href="../bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="../bower_components/core-list/core-list.html">
<link rel="import" href="../bower_components/core-pages/core-pages.html">
<link rel="import" href="../bower_components/core-ajax/core-ajax.html">
<!--{{hash}-->
<polymer-element name="progress-page" attributes="hash">
<template>
<template is="auto-binding" id="app" style=" height:100%; overflow: auto;">
<core-list data="{{data}}" flex style=" height:100%;">
<template>
<div class="row" layout horizontal center>
<div data-index="{{index}}">{{model.name}}</div>
</div>
</template>
</core-list>
</template>
</template>
<script>
Polymer('progress-page', {
ready: function () {
this.selected = 0;
var app = document.querySelector('#app');
app.data = generateContacts();
function generateContacts() {
var data = [];
for (var i = 0; i < 1000; i++) {
data.push({
name: 'dddd',
string: 'asd'
});
}
return data;
}
}
});
</script>
</polymer-element>
Cam somebody please tell me what's wrong ? This is 1:1 version from link I've added.
You shouldn't be using template is="auto-binding" inside a Polymer element. The whole point of an autobinding template is that it allows you to set up data binding outside a Polymer element.
So you're combining two concepts here. These two lines are what you'd use if you were using an auto-binding template in your main page:
var app = document.querySelector('#app');
app.data = generateContacts();
Here you're trying to retrieve a reference to the auto-binding template and add a data property to it.
This won't work in your context. '#app' is inside <progress-page>'s shadow DOM, so document.querySelector won't find it.
This line, on the other hand, is adding a property to the <progress-page> element, which is the proper thing to do if you're using core-list inside an element:
this.selected = 0;
So if you want to use an auto-binding template, eliminate the Polymer element and use the first approach (querySelector and assign app.data, app.selected).
If you want to create a Polymer element, eliminate the auto-binding template and use the second approach:
this.data = generateContacts();
this.selected = 0;
Here's a working version of this code with the auto-binding template removed:
http://jsbin.com/lofega/2/edit

Polymer <paper-dialog> selection issue

I am having a problem accessing paper-input elements that are inside a paper-dialog. I cant seem to get the value of the paper-input while its inside the paper-dialog, I just get a return value of null. I know there is something like this.$.element but I am confused on how to actually use it. Does the paper-dialog have to be inside a self binding template?
once a paper-dialog is opened it goes into the shadowdom of core-overlay-layer scoping the elements from regular selectors. you can access it's children with the this.$.element syntax if the dialog is inside a auto-binding template
<body>
<template id="app" is="auto-binding">
// other html content
<paper-dialog id="dialog">
<paper-input id="input"></paper-input>
</paper-dialog>
</template>
<script>
(function () {
var app = document.querySelector("#app");
app.addEventListener('template-bound', function () {
this.getValue = function () {
return this.$.input.value;
};
});
}());
</script>
</body>
the other option would be to use a auto-binding template like before and create a declarative variable for the input value
<body>
<template id="app" is="auto-binding">
// other html content
<paper-dialog id="dialog">
<paper-input value="{{inputValue}}"></paper-input>
</paper-dialog>
</template>
<script>
(function () {
var app = document.querySelector("#app");
app.addEventListener('template-bound', function () {
this.getValue = function () {
return this.inputValue;
};
});
}());
</script>
</body>
a way to get around using the auto-binding template would be to put the dialog in a custom element and enclose all it's functionality there that would allow you to use either of these methods.
i hope this helps.

polymer-ready event is not ready yet?

When I try document.querySelector('core-drawer-panel').togglePanel() in the console it works but when I do the following core-drawer-panel is not ready yet?
<template>
<core-drawer-panel forceNarrow>
</core-drawer-panel>
</template>
<script>
document.addEventListener('polymer-ready', function() {
document.querySelector('core-drawer-panel').togglePanel()
console.log('polymer-ready');
});
</script>
Note that I can not wrap it in a polymer element due to issues with other js frameworks.
try this
var template = document.querySelector('template');
template.addEventListener('template-bound', function () {
//code
});
with your element inside a template you need to look for template to be ready not polymer.