Polymer 2.0 too many ifs - polymer

I'm looking for a better optimized solution to have too many if's in Polymer 2.0. For example i'm building a table object, where each cell can be text, buttons, links, objects, ect. I want the user to be able to enter a 2D array and have the Polymer 2.0 object be able to pick which markup to use. My current solution (below) simple has several if statements, but this means that every cell if going to call each statement. Is there a a better way to handle this?
<template is="dom-if" if="[[matchCellType(cell, 'button')]]">
<UI-Button id='[[cell.button.ID]]' class$='[[cell.button.class]]'>[[cell.button.text]]</UI-Button>
</template>
<template is="dom-if" if="[[matchCellType(cell, 'object')]]">
<span class="object-toggle"></span>[[cell.title]]
<div class="properties">
<template is="dom-repeat" items="[[getProps(cell)]]">
<div class="properties_row"><div class="properties_cell"><b>[[item.title]]:</b></div><div style="display: table-cell">[[item.val]]</div></div>
</template>
</div>
</template>
<template is="dom-if" if="[[matchCellType(cell, 'link')]]">
<a target="_blank" href='[[cell.link.href]]'>[[cell.link.text]]</a>
</template>
<template is="dom-if" if="[[matchCellType(cell, 'cell')]]">
[[cell]]
</template>
<template is="dom-if" if="[[matchCellType(cell, 'textArea')]]">
<ui-text-area rows="[[cell.textArea.rows]]" cols="[[cell.textArea.cols]]" id='[[cell.textArea.id]]' class$='[[cell.textArea.class]]' text= [[cell.textArea.text]]></ui-text-area>
</template>

Lots of calls to matchCellType don't harm if it isn't a costly computation (if it were, you could update a property in an observer and test on the property instead)
Factor out the series of ifs into a component so you don't clutter up your table
As an alternative to using dom-ifs, compute an attribute or style class from the cell, render all elements always, and use CSS to have only the matching elements be visible. This produces much more DOM elements, but may still be more performant because browsers handle hidden or display:none elements very efficiently
Instead of stamping with several dom-ifs, you could create and remove nodes imperatively

Related

What is a proper replacement of paper-menu and paper-submenu in Polymer 3?

I have a polymer 1 application that used paper-menu and paper-submenu. I am rewriting it in Polymer 3. What is the general consensus for its replacement? I have searched for this and have found nothing. It would be good if the documentation for paper-menu and paper-submenu showed its replacement.
You can refer MWC-Menu for polymer 3 support link here
I replaced paper-menu and paper-submenu with the Polymer 3 elements vaadin-accordion and paper-listbox
<vaadin-accordion>
<template is="dom-repeat" items="{{sources}}">
<vaadin-accordion-panel theme="filled">
<div slot="summary">[[item.name]]</div>
<paper-listbox>
<template is="dom-repeat" items="{{item.models}}">
<paper-item on-tap="selectModel">[[item.name]]</paper-item>
</template>
</paper-listbox>
</vaadin-accordion-panel>
</template>
</vaadin-accordion>

Polymer - Nesting a content tag inside a conditional template

I'm using a conditional template to distribute content that is passed into the element. If the condition is true, it will show the first content element, otherwise the second. I noticed that when I update the condition the already distributed content is not updated. Once it is visible it will remain visible.
My first attempt looked like this:
<template is="dom-if" if="{{test}}">
<content select=".first">
</content>
</template>
<template is="dom-if" if="{{!test}}">
<content select=".second">
</content>
</template>
I noticed that it will work, if the content is wrapped in another element.
<template is="dom-if" if="{{test}}">
<div>
<content select=".first">
</content>
</div>
</template>
<template is="dom-if" if="{{!test}}">
<div>
<content select=".second">
</content>
</div>
</template>
I've created a plunker that demonstrates both cases.
Is there an explanation for this behaviour? Is it on purpose or a bug?
This is actually per design. Here`s what the Polymer team had to say on the issue on Github.
Hiding a <content> has no effect on the visibility of its distributed children (per spec), so your options are to wrap the content with a wrapper element that can be hidden (and will hide the distributed children), or use restamp which will pull the <content> out of the DOM all together.
It is slightly unintuitive that the restamp and non-restamp setups work differently, however it is a result of the non-restamp behavior which hides rather than destroying DOM as a performance optimization.

What's the right way to define the <content> tag?

When defining an insertion point for light DOM in WebComponents, is there any difference between these two syntaxes?
<template id="my-element">
<content></content>
</template>
and
<template id="my-element">
<content/>
</template>
What's the right or the best way to define the tag?
I tested both syntaxes in Firefox/Chrome and they behave identically (at least in a simple test).
Look at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/content :
Tag omission: None, both the starting and ending tag are mandatory.

How do I use dom-repeat in Polymer binding to a dictionary

I am trying to bind to data below which is a dictionary
<template is="dom-repeat" items="{{data}}">
</template>
I have found a similar question here Polymer: How to loop and render HTML to screen
<template repeat="{{customer, i in customers}}">
<div>{{i}}, {{customer.name}}</div>
</template>
but I am not sure if this applies to Polymer 1.0 and cannot find anything in the doc.
How do I do this in 1.0?
Cheers
What you have in the first example is correct for Polymer 1.0. Here is the documentation for the template repeat (dom-repeat).
<template is="dom-repeat" items="{{data}}">
<div>
<span>{{index}}</span> <span>{{item}}</span>
</div>
</template>

How to loop through nested Firebase keys in Polymer

So, I have a Polymer project that is saving to Firebase. My data looks like this:
What I'm trying to do is loop through the teams property in the data. Considering Polymer only loops through Arrays right now, this is proving to be pretty challenging (since Firebase preferably returns data as objects). So far, I can loop through the keys and get the teams, but can't get into the teams to loop through it. Here is my code:
<template repeat="{{key in keys}}">
<div class="tile">
<paper-shadow z="2" class="card" animated>
<div id="header" class="header"></div>
<div class="content">
<p>{{data[key]}}</p>
<span>{{team.club}}</span>
</div>
<footer horizontal layout>
<paper-button id="teamview" on-tap="{{viewTeam}}" flex>VIEW</paper-button>
<span flex></span>
<paper-button id="teamDelete" on-tap="{{deleteTeam}}">DELETE</paper-button>
<paper-button id="teamEdit" on-tap="{{editTeam}}">EDIT</paper-button>
</footer>
</paper-shadow>
</div>
</template>
I feel like I've tried almost every scenerio. Every time I try and loop one more level with repeat="{{team in key}}" it breaks. Seeing if maybe some one else has a better perspective on this? Thanks in advance!
You need to bind the data, id and keys like this I think.
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../firebase-element/firebase-element.html">
<!--
Element providing solution to displaying value from firebase.
##### Example
<firebase-repeat-element></firebase-repeat-element>
#element fb-repeat-element
#blurb Element providing solution to displaying value from firebase.
#status alpha
#homepage http://basicelements.github.io/firebase-repeat-element
-->
<polymer-element name="firebase-repeat-element" attributes="firebaseName">
<template>
<firebase-element location="https://{{firebaseName}}.firebaseio.com/members/{{id}}" data="{{data}}" keys="{{keys}}"></firebase-element>
<template repeat="{{id in keys}}">
<h2>{{data[id]['name']}}</h2>
<img src="{{data[id]['image']}}">
</template>
</template>
<script>
Polymer({
});
</script>
</polymer-element>
Be free to fork it #https://gist.github.com/ed2ba06d5a16d11381d9.git
So, the way I found out needs more in-depth explaining regarding Polymer and Firebase. First off, when you enter your location attribute in the firebase-element, whenever you are sourcing your data and keys, it is specifically with that location - not your data as a whole.
Therefore, the problem I was having was rooted in my location attribute. Once I changed my location to specify the exact nested level I wanted to push and source data from - all was well. The end code looked like this:
<firebase-element id="fbase"
location="https://volleyball-app.firebaseio.com/{{user.uid}}/userTeams"
data="{{userTeams}}" keys="{{keys}}" dataReady="{{userReady}}">
</firebase-element>
<template repeat="{{key in keys}}">
<div class="content">
<p>{{userTeams[key]['team']}}</p>
<span>{{userTeams[key]['club']}}</span>
</div>
</template>
What this is doing is repeating through all the keys in the <firebase-element id="fbase"
location="https://volleyball-app.firebaseio.com/{{user.uid}}/userTeams location (nothing more). From there I'm grabbing the team property in each key.