Polymer, issue with binding array to paper slider

2019-08-09 06:59发布

问题:

Here is example of the issue: Plunk

The initial value, 31, is not binding when changing the slider. Array value 31 is seated on the initiation, but can not be reseated after change.

How to properly bind slider to the array?

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

<link href="paper-input/paper-input.html" rel="import">
<link href="paper-slider/paper-slider.html" rel="import">
<link href="google-chart/google-chart.html" rel="import">

<dom-module id="dynamic-chart">
  <template>

    Binded values:
    <br>
    arrayItem: {{arrayItem(rows.*, 0, 1)}}
    <br>
    arrayBase: {{arrayBase(rows.*)}}

    <hr>

    Jan slider:
    <paper-slider min="1" 
                  max="31" 
                  value="{{rows.0.1}}"
                  pin
                  editable>
    </paper-slider>

  </template>
  <script>
    Polymer({
      is: 'dynamic-chart',

      properties: {
        rows: {
                type: Array,
                notify: true,
              },
      },

      //domReady:
      attached: function() {
         this.async(function() {
            this.rows=[ ["Jan", 31],["Feb", 28],["Mar", 31] ];
            console.log('domReady');
         });

      },

      // first argument is the change record for the array change,
      // change.base is the array specified in the binding
      arrayItem: function(change, index, path) {

        console.log('arrayItem');
        return this.get(path, change.base[index]);
      },

      arrayBase: function(change) {

        console.log('arrayBase');
        return change.base;
      },

    });
  </script>
</dom-module>

<dynamic-chart>
</dynamic-chart>

Update: array-selector (simple example) element can be used for this task too.

回答1:

You are trying to bind your array first element rows.0.1 which is a constant value, 31 to the value of the paper-slider. What is happening that the arrayItem get notifies when its value change i.e !== 31.

What you should do is to bind the max value like this. Plunkr

<base href="http://polygit.org/polymer+:master/components/">

<!--<base href="http://polygit.org/components/">-->

<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">

<link href="paper-input/paper-input.html" rel="import">
<link href="paper-slider/paper-slider.html" rel="import">
<link href="google-chart/google-chart.html" rel="import">


<dom-module id="dynamic-chart">
  <template>

    init value, 31, can't be binded back to arrayItem once the slider in changed:
    <br>
    <br> Binded values:
  
    <br><i>the arrayItem get notifies when its value change i.e !== 31</i>
    <br> arrayItem: {{arrayItem(rows.*, 0, 1)}}
    <br> arrayBase: {{arrayBase(rows.*)}}

  
    <h1>paper-slider 1</h1>
    <div>Rows First Element: <span>{{rows.0.1}}</span> ==> Constant value </div>
    <div>paper-slider Value: <span id="ps1Value"></span></div>
    <paper-slider min="1" max="31" pin editable value="{{rows.0.1}}" id="ps1">
    </paper-slider>

       <!-- You need  to bind the paper-slider max to the selected rows item-->
    <!-- Changing the max value to {{rows.1.1}} rows second element -->
    <h1>paper-slider 2</h1>
    <div>Rows Second  Element: <span>{{rows.1.1}}</span> ==> Constant value </div>
    <div>paper-slider Value: <span id="ps2Value"></span></div>
    <paper-slider min="1" max="{{rows.1.1}}" pin editable value="{{_value2}}" id="ps2">
    </paper-slider>



  </template>
  <script>
    Polymer({
      is: 'dynamic-chart',

      properties: {
        rows: {
          type: Array,
          notify: true,
        },       

        _value2: {
          type: Number,
          value:0,
          observer: '_value2Changed'
        }

      },
        // you can also use an obsersver instead of the addEventListener
      _value2Changed: function(val) {
        console.log("this is paper-slider #2  value "+ val);
      },

      ready: function() {
        //events for paper slider #1
        document.querySelector('#ps1').addEventListener('value-change', function(e) {
          document.querySelector('#ps1Value').textContent = e.target.value;

        });
        //events for paper slider #1
        document.querySelector('#ps2').addEventListener('value-change', function(e) {
          document.querySelector('#ps2Value').textContent = e.target.value;

        });
      },

      //domReady:
      attached: function() {
        this.async(function() {

          //init value, 31, can't be seated back once the slider in changed:
          this.rows = [
            ["Jan", 31],
            ["Feb", 28],
            ["Mar", 31]
          ];
          console.log('domReady');
          //console.log(this.rows);
        });

      },

      // first argument is the change record for the array change,
      // change.base is the array specified in the binding
      arrayItem: function(change, index, path) {

        console.log('arrayItem');
        //console.log(change);
        //console.log(index);
        //console.log(path);
        //console.log(this.get(path, change.base[index]));

        // this.get(path, root) returns a value for a path
        // relative to a root object.
   
        return this.get(path, change.base[index]);

      },


      arrayBase: function(change) {

        console.log('arrayBase');
        return change.base;
      },

    });
  </script>
</dom-module>

<dynamic-chart>
</dynamic-chart>

It will be better to have your rows as object instead of Array of objects,this way:

    rows:{
       type: Array,
      notify: true,
      value:function(){
        return [
            {"label":"Jan", max:31},
        {"label":"Feb", max:28},
        {"label":"Mar", max:31}
          ];
      }
    },