Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dom-repeat data binding: not working as expected #1758

Closed
vl4dt opened this issue Jun 5, 2015 · 10 comments
Closed

dom-repeat data binding: not working as expected #1758

vl4dt opened this issue Jun 5, 2015 · 10 comments

Comments

@vl4dt
Copy link

vl4dt commented Jun 5, 2015

What am I missing?
http://jsbin.com/xukibu/1/

Output (excerpt):
http://jsbin.com/videze/2/

@vl4dt vl4dt changed the title dom-repeat: not working as expected? dom-repeat data binding: not working as expected Jun 5, 2015
@punzki
Copy link

punzki commented Jun 5, 2015

As per https://www.polymer-project.org/1.0/docs/migration.html#data-binding

A binding must replace the entire text content of a node, or the entire value of an attribute. So string concatenation is not supported. For attribute values, you can use computed bindings instead of string concatenation. For text content, you can also add additional nodes (for example, wrap the binding in a tag).

Try:

    <template is="dom-repeat" items="{{items}}">
      <p><span>{{item.code}}</span> - <span>{{item.name}}</span></p>
    </template>

@robrez
Copy link

robrez commented Jun 5, 2015

Or something like...

<span>{{_concat(item.code, item.name)}}</span>

_concat: function(v1, v2) {
  return v1 + " - " + v2;
}

@vl4dt
Copy link
Author

vl4dt commented Jun 5, 2015

Thanks both, I read and still missed it when trying in code, but still I tried both approaches, jshint is not complaining but still keep getting similar results:

Code:
http://jsbin.com/xukibu/4/

Output:
http://jsbin.com/videze/3/

@punzki
Copy link

punzki commented Jun 5, 2015

@vl4dt - Try changing your items property to:

        items: {
          type: Array,
          value: function() { return []; },
          notify: true
        }

As per https://www.polymer-project.org/1.0/docs/devguide/properties.html#configure-values (_emphasis_ mine):

The value may either be a primitive value, or _a function that returns a value_ (which should be used for initializing Objects and _Arrays_ to avoid shared objects on instances).

@robrez
Copy link

robrez commented Jun 5, 2015

Maybe you need to use the new set or notify api..

https://www.polymer-project.org/1.0/docs/devguide/properties.html#observing-path-changes

Try a notify on items

@arthurevans
Copy link

@robrez is correct. this.items.push(...) should be:

      this.push('items', {
        code: i + 1,
        name: 'Item #' + (i + 1)
      });

Alternately, if you're refreshing the entire list, you could do:

    var tmp = [];

    for (var i = 0; i < 10; i++) {
      tmp.push({
        code: i + 1,
        name: 'Item #' + (i + 1)
      });
    }

    this.items = tmp;

This takes advantage of the fact that changing a direct property like items invokes its setter and automatically updates anything that's registered interest in that path (like the dom-repeat).

@punzki
Copy link

punzki commented Jun 6, 2015

It would also be helpful if you share the markup that generates your output (the one that uses your element)

@vl4dt
Copy link
Author

vl4dt commented Jun 6, 2015

Thanks all, finally works!

@punzki I was lazy and just took the Polymer Starter Kit, modified the index.html that comes with the it, replaced the contact section content like this:

<section data-route="contact">
  <paper-material elevation="1">

    <el-test></el-test>

  </paper-material>
</section>

The final solution was the sum of all fixes suggested, both approaches suggested by @arthurevans and @robrez worked just fine, the binding was wrong as @punzki pointed, to sum it all, here is the final and working code:

<dom-module id="el-test">
    <style>
      :host {
        display: block;
      }

      @media (max-width: 600px) {
        h1.paper-font-display1 {
          font-size: 14px;
        }
      }
    </style>
  <template>
    <h1 class="paper-font-display1">
      List of Items
      <paper-icon-button
        icon="refresh"
        on-tap="refreshItems">
      </paper-icon-button>

      <paper-icon-button
        icon="refresh"
        on-tap="refreshItemsB">
      </paper-icon-button>
    </h1>

    <p>This is the complete list of items</p>

    <div>-- START --</div>

    <template is="dom-repeat" items="{{items}}">
      <p>
        <span>{{item.code}}</span> - <span>{{item.name}}</span>
         =
        <span>{{_concat(item.code, item.name)}}</span>
      </p>
    </template>

    <div>-- END --</div>
  </template>
</dom-module>

<script>
  (function() {
    Polymer({
      is: 'el-test',

      properties: {
        greeting: {
          type: String,
          value: 'Bienvenido',
          notify: true
        },
        items: {
          type: Array,
          value: function() { return []; },
          notify: true
        }
      },

      refreshItems: function() {
        var tmp = [];

        for (var i = 0; i < 10; i++) {
          tmp.push({
            code: i + 1,
            name: 'Item #' + (i + 1)
          });
        }

        this.items = tmp;
      },

      refreshItemsB: function() {
        for (var i = 0; i < 10; i++) {
          this.push('items', {
            code: i + 1,
            name: 'Item #' + (i + 1)
          });
        }
      },

      _concat: function(v1, v2) {
        return v1 + ' - ' + v2;
      }
    });
  })();
</script>

Thanks a lot!

@vl4dt vl4dt closed this as completed Jun 6, 2015
@sunnyagain
Copy link

I am trying to assign value to attribute inside but its not working while values are displayed correctly in text context.
whats wrong with attribute context ?

example:

routes = [{"name":"foo", "path": "bar"}, {"name":"foo1", "path": "bar1"}];
<template is="dom-repeat" items="{{routes}}" as="route">
<a href="#" data-route="{{route.path}}"><span>{{route.name}}</span></a>
</template>

in above case data-route for anchor is not set but name is appearing.
I have tried switching variables then path comes in text context but data-route attribute is still missing.

any help ..
Thanks in advance .. :)

@robrez
Copy link

robrez commented Sep 1, 2015

@sunnyagain

Try data-route$="{{route.path}}"

The docs talk about property vs attribute binding here:
https://www.polymer-project.org/1.0/docs/devguide/data-binding.html#attribute-binding

And binding to native elements here:
https://www.polymer-project.org/1.0/docs/devguide/data-binding.html#native-binding

The spec recommends using $= for certain types of attributes / native elements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants