Polymer 1.0 - Issue with displaying values inside template is="dom-repeat"
Asked Answered
N

4

3

While migrating to Polymer 1.0 from 0.5 I have come across an interesting thing. Thought it might help others having similar problem.

I have an element where I am using <template is="dom-repeat" items="{{customers}}">...</template>. The problem I am facing is I have to place every single property binding inside a HTML element. The code below what I intended to write:

<template is="dom-repeat" items="{{customers}}">
  <div>
    {{item.name}}<br />
    {{item.addr}}, {{item.addr2}}<br />
    {{item.phone}}
  </div>
</template>

But it is only displaying the value for {{item.name}}. The reason is other property bindings are not wrapped within separate HTML tags, they are not displaying at all!

I tried the following but didn't work either:

<template is="dom-repeat" items="{{customers}}">
  <div>
    <p>{{item.name}}</p>
    <span>{{item.addr}} {{item.addr2}}</span>
  </div>
</template>

Means, I put {{item.name}} inside a <p>...</p> tag and placed {{item.addr}} and {{item.addr2}} inside a single <span>...</span> tag.

Then I went on and put every single property binding wrapped by their own HTML tags like the following:

<template is="dom-repeat" items="{{customers}}">
  <div>
    <p>{{item.name}}</p>
    <span style="display:block">{{item.addr}}, <span>{{item.addr2}}</span></span>
    <span style="display:block;">{{item.phone}}</span>
  </div>
</template>

and it works!!

I truly have no idea whether it is a bug of 1.0 or there is something I am doing wrong! If anybody knows the answer please help.

Thanks in advance

Nenitanenney answered 2/6, 2015 at 15:19 Comment(4)
String concatenation is not supported inside a tag, and the tag can’t contain any whitespace. polymer-project.org/1.0/docs/devguide/…Marchal
Thanks for your quick reply. So that means I cannot bind more than one property values inside one tag? However it was possible in 0.5. Is this a a new rule set in 1.0?Nenitanenney
Not a rule actually. Because 0.8 was a total rewrite, some things were not added back. This was one of those. But this is only temporary as string concatenation will be brought back post 1.0. It's in their current roadmap.Marchal
That would be nice actually :)Nenitanenney
F
7

You're not doing anything wrong. With the introduction of Polymer 0.9 (and later 1.0) data-binding to the content of text nodes only works if you wrap everything into its own element.

See the Polymer documentation:

The binding annotation must currently span the entire content of the tag

So you have to remove all whitespace and other characters for it to work.

Example from the documentation:

<!-- this works -->
<template>   
  First: <span>{{first}}</span><br>
  Last: <span>{{last}}</span>
</template>

<!-- Not currently supported! -->
<div>First: {{first}}</div>
<div>Last: {{last}}</div>

<!-- Not currently supported! -->
<div>
  {{title}}
</div>

Edit

As of Polymer 1.2, the issue described in the question is no longer problematic / erroneous. Compound bindings now work, see release notes on the Polymer blog.

Fanfani answered 2/6, 2015 at 15:32 Comment(2)
Thank you LeBird for your quick and helpful response! I went through the migration document but never realized this is a new rule set :) However, I don't understand why this restriction has been imposed. What if string concatenation still remains?Nenitanenney
We're planning to add it back, it just didn't make the 1.0 cutMethionine
I
2

Just a heads up, for element attributes though you can use something like a helper function for string concatenation. Here's an example.

<my-foo fullname="{{computeFullName(firstname, lastname)}}">
        Hi, my name is <span>{{firstname}}</span>.
</my-foo>


...

computeFullName: function(first, last) {
  return first + ' ' + last;
}

And here's the link: https://www.polymer-project.org/1.0/docs/migration.html#data-binding

EDIT: For node content as well, string concatenation can be done using computed properties (I call them helper functions). Here's an example,

<dom-module id="x-custom">
  <template>
    My name is <span>{{fullName}}</span>
  </template>
</dom-module>

<script>
  Polymer({

    is: 'x-custom',

    properties: {

      first: String,

      last: String,

      fullName: {
        type: String,
        // when `first` or `last` changes `computeFullName` is called once
        // (asynchronously) and the value it returns is stored as `fullName`
        computed: 'computeFullName(first, last)'
      } 

    },

    computeFullName: function(first, last) {
      return first + ' ' + last;
    }

    ...

  });
</script>
Izmir answered 2/6, 2015 at 16:19 Comment(0)
T
2

With Polymer 1.2 you example code will actually work. Binding annotations no longer need to span the entire tag.

Example:

<div>first name: [[name.first]] last name: [[name.last]]</div>

https://blog.polymer-project.org/releases/2015/11/02/release-1.2.0/

Tovatovar answered 13/1, 2016 at 14:52 Comment(1)
That's a good news. I actually have a plan to upgrade my application to 1.2 next week. Thanks for the link. I will go through it soon. The most welcome fix is Compound bindings can eliminate the need for computed bindings in many cases.Nenitanenney
M
1

You'll want to use a computed property to combine values. Search for them on this page https://www.polymer-project.org/1.0/docs/devguide/properties.html

Methionine answered 3/6, 2015 at 15:25 Comment(2)
And what to do with dom-repeat? Where to concat string and {{item}}?Semaphore
See joseph_k's answer below. I think using a computed property is a better solution to this problem than adding unnecessary HTML markupMethionine

© 2022 - 2024 — McMap. All rights reserved.