Search code examples
polymerpolymer-2.xiron-elements

Using <iron-selector> in Polymer 2.x


I am trying to demo <iron-selector>. In the demo, I want to log to the console when the user selects a new value from the list. What am I doing wrong?

Here is the JSBin.

http://jsbin.com/ciceguqore/1/edit?html,console,output
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>

  <base href="//polygit.org/polymer+:master/components/">
  <script src="webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="polymer/polymer-element.html">
  <link rel="import" href="iron-selector/iron-selector.html">

</head>
<body>
  <dom-module id="my-el">
    <template>
      <iron-selector selected="[[route]]">
        <div>Item 1</div>
        <div>Item 2</div>
        <div>Item 3</div>
      </iron-selector>
    </template>
    <script>
      class MyEl extends Polymer.Element {
        static get is() { return 'my-el' }

        static get properties() { return {
          route: {
            type: Number,
            notify: true,
            observer: '_routeChanged',
          },
        }}

        constructor() {
          super();
        }

        _routeChanged(route) {
          console.log('route', route);
        }

      }

      customElements.define(MyEl.is, MyEl);
    </script>
  </dom-module>

  <my-el></my-el>
</body>
</html>

Solution

  • In order to change the value of route you have to use two-way binding. Since iron-selector is not able to change the value of route the observer is not being triggered.

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>JS Bin</title>
    
      <base href="//polygit.org/polymer+:master/components/">
      <script src="webcomponentsjs/webcomponents-lite.js"></script>
      <link rel="import" href="polymer/polymer-element.html">
      <link rel="import" href="iron-selector/iron-selector.html">
    
    </head>
    
    <body>
      <dom-module id="my-el">
        <template>
        <style>
        .iron-selected{color:blue}
        </style>
        <p>Route value using two way binding in iron-selector: [[route]] </p>
          <iron-selector selected="{{route}}">
            <div>Item 1</div>
            <div>Item 2</div>
            <div>Item 3</div>
          </iron-selector>
          
          <p>Route value using one way binding in iron-selector: [[route]]</p>
          <iron-selector selected="[[route]]">
            <div>Item 1</div>
            <div>Item 2</div>
            <div>Item 3</div>
          </iron-selector>
          [iron-selector is working but it cannot update the value of route]
        </template>
        <script>
          class MyEl extends Polymer.Element {
            static get is() {
              return 'my-el'
            }
    
            static get properties() {
              return {
                route: {
                  type: Number,
                  notify: true,
                  observer: '_routeChanged',
                },
              }
            }
    
            constructor() {
              super();
            }
    
            _routeChanged(route) {
              console.log('route', route);
            }
    
          }
    
          customElements.define(MyEl.is, MyEl);
        </script>
      </dom-module>
    
      <my-el></my-el>
    </body>
    
    </html>

    You can also use selected-changed of iron-selector event which is fired when the selected property changes. Example:

    <iron-selector on-selected-changed="_onSelectedChanged" selected="[[route]]">
     <div>Item 1</div>
     <div>Item 2</div>
     <div>Item 3</div>
    </iron-selector>
    
    _onSelectedChanged(e){
      console.log('route',e.detail.value);
    }