在dom-repeat items属性上计算绑定

时间:2016-06-06 18:30:41

标签: polymer

我正在构建一个相对简单的页面,其中动态创建了一系列纸质标签和核心页面。想法是用户 - 通过纸张输入 - 指示需要的纸张标签和核心页面的数量,并使用dom-repeat自动添加这些页面和核心页面。该功能的第一部分已经实现,但我遇到第二部分问题。

在纸页内部,我需要3个纸张输入和按钮,因此用户可以创建/删除新输入。我的想法是实现一个函数,它将创建许多数组,如用户指示并用输入填充它们。

我已经实现了一个计算绑定来滚动每个数组,但是没有用。创建的X铁页没有问题,但没有添加任何输入。

以下是代码:

{{1}}

2 个答案:

答案 0 :(得分:0)

主要问题是这一行:

<template id="inputs" is="dom-repeat" items="{{concat(tabArray.array, index)}}">

您不清楚自己尝试使用concat(tabArray.array, index)做什么。 array上没有tabArray属性,但即使有,concat()只是连接其参数,并且可能会返回string,这是模板的无效输入转发器(即转发器items必须绑定到Array)。删除无效的template代码可以解决问题。

另请注意,paper-tabsiron-pages绑定到未初始化的selected属性,因此在单击选项卡之前不会显示任何页面视图。您可以通过声明具有默认值的selected属性来解决此问题。

这是一个有效的演示:

&#13;
&#13;
<head>
  <meta charset="utf-8">
  <base href="https://polygit.org/polymer+1.5.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="iron-label/iron-label.html">
  <link rel="import" href="iron-pages/iron-pages.html">
  <link rel="import" href="paper-input/paper-input.html">
  <link rel="import" href="paper-button/paper-button.html">
  <link rel="import" href="paper-tabs/paper-tabs.html">
  <link rel="import" href="paper-tabs/paper-tab.html">
</head>

<body>
<protocolo-app></protocolo-app>

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

    .card {
      box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
      padding: 16px;
      margin: 24px;
      border-radius: 5px;
      background-color: #fff;
      color: #757575;
    }

    .inputGray {
      background-color: #555;
      color: #fff;
    }

    h1 {
      font-size: 22px;
      margin: 16px 0;
      color: #212121;
    }

    paper-tabs[grayTab] {
      background: #eee;
      margin-top: 3%;
      margin-bottom: 3%;
    }

    .flex {
      @apply(--layout-horizontal);
    }

    .flex-horizontal-with-ratios {
      @apply(--layout-horizontal);
    }

    .flexchild {
      @apply(--layout-flex);
    }

    .flex2child {
      @apply(--layout-flex-2);
    }

    .flex3child {
      @apply(--layout-flex-3);
    }

    .flex-center-justified {
      @apply(--layout-horizontal);
      @apply(--layout-center-justified);
    }

    .flex-equal-justified {
      @apply(--layout-horizontal);
      @apply(--layout-justified);
    }

    .flex-equal-around-justified {
      @apply(--layout-horizontal);
      @apply(--layout-around-justified);
    }

    paper-button.gray {
      background: #eee;
      color: #000;
    }

    paper-button.gray:hover {
      background: #555;
    }

    paper-button[disabled],
    paper-button[toggles][active] {
      background: red;
    }
  </style>

  <template>
    <div class="card">
      <h1>Alta de Protocolos</h1>
      <div class="cointainer flex-horizontal-with-ratios">
        <div class="flex2child">
          <iron-label>Nombre de Protocolo</iron-label>
        </div>
        <div class="flexchild">
          <iron-label>Núm. Visitas</iron-label>
        </div>
      </div>
      <div class="cointainer flex-horizontal-with-ratios">
        <div class="flex2child">
          <paper-input name="protocol" id="protocol" value="{{protocol}}"></paper-input>
        </div>
        <div class="flexchild">
          <paper-input name="visit" id="visit" value="{{visits}}" prevent-invalid-input
                       allowed-pattern="[0-9]" on-change="visitChanged"></paper-input>
        </div>
      </div>
      <!-- Tab's Element-->
      <paper-tabs selected="{{selected}}" scrollable no-slide noink grayTab>
        <template id="tabs" is="dom-repeat" items="{{tabArray}}">
          <paper-tab>{{item.value}}</paper-tab>
        </template>
      </paper-tabs>
      <!-- /Tab's Element-->
      <!-- iron-pages Element's-->
      <iron-pages selected="{{selected}}">
        <template id="pages" is="dom-repeat" items="{{tabArray}}">
          <div>
            <!--<template id="inputs" is="dom-repeat" items="{{concat(tabArray.array, index)}}">-->
              <div class="container flex">
                <div>
                  <paper-input id="input" value="{{item.value}}"
                               placeholder="{{item.placeholder}}"></paper-input>
                </div>
                <div>
                  <paper-button class="gray" raised on-tap="delInput">Eliminar</paper-button>
                </div>
              </div>
            <!--</template>-->
            <div class="container flex">
              <paper-button class="gray" raised on-tap="addInput">Agregar</paper-button>
            </div>
          </div>
        </template>
      </iron-pages>
      <!-- /iron-pages Element's-->
      <div class="container flex-center-justified">
        <div>
          <paper-button class="gray" raised>Cancelar</paper-button>
          <paper-button class="gray" raised>Guardar</paper-button>
        </div>
      </div>
    </div>
  </template>
  <script>
    Polymer({

      is: 'protocolo-app',

      properties: {
        protocol: {
          type: String,
          value: ""
        },
        visits: {
          type: Number,
          value: 3,
          notify: true
        },
        tabArray: {
          type: Array,
          value: [{value: "visita1"}, {value: "visita2"}, {value: "visita3"}]
        },
        inputArray: {
          type: Array,
          value: [{value: "", placeholder: "t1_input1"}, {value: "", placeholder: "t1_input2"}, {
            value: "",
            placeholder: "t1_input3"
          }]
        },
        selected: {
          type: Number,
          value: 0
        }
      },

      //funcion que agrega input's
      addInput: function() {
        this.push('inputArray0', {value: "", placeholder: ""});
      },
      //funcion que elimina input's
      delInput: function(e) {
        this.splice('inputArray0', e.model.index, 1);
      },
      creaArrayTabs: function(e) {
        console.log(this.value);
      },
      concat: function(v1, v2) {
        var res = v1 + v2;
        alert("Concatenacion: " + res);
        return v1 + v2;
      },
      //funcion que carga los arrays necesarios para la aplicacion
      visitChanged: function(e) {
        //alert("Valor: " + this.$.visit.value);
        //limpiamos el array para agregar las nuevas tabs
        this.splice('tabArray', e.model);
        //asignamos a la variable max el valor del input
        var max = this.$.visit.value;
        for (i = 0; i < max; i++) {
          //alert("Prueba " + i);
          this.push('tabArray', {value: "Visita " + i, array: "inputArray"});
          this['inputArray' + i] = [];
          for (j = 0; j < 3; j++) {
            this.push('inputArray' + i, {value: "", placeholder: "t" + i + "_input" + j});
          }
        }
      }
    });
  </script>
</dom-module>
</body>
&#13;
&#13;
&#13;

codepen

请注意,您的代码中似乎存在其他问题,但这超出了此问题的范围。

答案 1 :(得分:0)

经过多次尝试,唯一的解决方案是迁移到多维数组结构并修改add和del函数以与新的数组结构进行交互。

最终代码:

    <!DOCTYPE html>
<html>
<head>
  <!-- Dependencias/Elementos -->
  <link rel="import" href="../../bower_components/polymer/polymer.html">
  <link rel="import" href="../../bower_components/iron-label/iron-label.html">
  <link rel="import" href="../../bower_components/iron-pages/iron-pages.html">

  <link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
  <link rel="import" href="../../bower_components/paper-input/paper-input.html">
  <link rel="import" href="../../bower_components/paper-button/paper-button.html">
  <link rel="import" href="../../bower_components/paper-tabs/paper-tabs.html">

</head>

<dom-module id="protocolo-app">
    <style>
      :host {
        display: block;
      }
      .card {
        box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
        padding: 16px;
        margin: 24px;
        border-radius: 5px;
        background-color: #fff;
        color: #757575;
      }
      .inputGray{
        background-color: #555;
        color: #fff;
      }
      h1 {
        font-size: 22px;
        margin: 16px 0;
        color: #212121;
      }
      paper-tabs[grayTab]{
        background: #eee;
        margin-top: 3%;
        margin-bottom: 3%; 
      }
      .flex {
        @apply(--layout-horizontal);
      }
      .flex-horizontal-with-ratios {
        @apply(--layout-horizontal);
      }
      .flexchild {
        @apply(--layout-flex);
      }
      .flex2child {
        @apply(--layout-flex-2);
      }
      .flex3child {
        @apply(--layout-flex-3);
      }
      .flex-center-justified {
        @apply(--layout-horizontal);
        @apply(--layout-center-justified);
      }
      .flex-equal-justified {
        @apply(--layout-horizontal);
        @apply(--layout-justified);
      }
      .flex-equal-around-justified {
        @apply(--layout-horizontal);
        @apply(--layout-around-justified);
      }
      paper-button.gray {
      background: #eee;
      color: #000;
      }
      paper-button.gray:hover {
      background: #555;
      }
      paper-button[disabled],
      paper-button[toggles][active] {
      background: red;
      }
    </style>

  <template> 
    <div class="card">
      <h1>Alta de Protocolos</h1>
      <div class="cointainer flex-horizontal-with-ratios">
        <div class="flex2child">
          <iron-label>Nombre de Protocolo</iron-label>
        </div>
        <div class="flexchild">
          <iron-label>Núm. Visitas</iron-label>
        </div>
      </div>
      <div class="cointainer flex-horizontal-with-ratios">
        <div class="flex2child">
          <paper-input name="protocol" id="protocol" value="{{protocol}}"></paper-input>
        </div>
        <div class="flexchild">
          <paper-input name="visit" id="visit" value="{{visits}}" prevent-invalid-input allowed-pattern="[0-9]" on-change="visitChanged"></paper-input>
        </div>
      </div>
      <paper-input id="selection" hidden="true" value="{{selected}}"></paper-input>
        <!-- Tab's Element-->
        <paper-tabs selected="{{selected}}" scrollable no-slide noink grayTab>
          <template id="tabs" is="dom-repeat" items="{{tabArrayTest}}" as="tab">
           <paper-tab>{{tab.tabName}}</paper-tab>
          </template>
        </paper-tabs>
        <!-- /Tab's Element-->
        <!-- iron-pages Element's-->
        <iron-pages selected="{{selected}}">
          <template id="pages" is="dom-repeat" items="{{tabArrayTest}}" as="tabInput">
            <div>
              <template id="inputs" is="dom-repeat" items="{{tabInput.inputs}}" as="inp">
                <div class="container flex">
                  <div>
                    <paper-input id="input" value= "{{inp.value}}" placeholder="{{inp.placeholder}}"></paper-input>
                  </div>
                  <div>
                    <paper-button class="gray" raised on-tap="delInput">Eliminar</paper-button>
                  </div>
                </div>
              </template>
              <div class="container flex">
                <paper-button class="gray" raised on-tap="addInput">Agregar</paper-button>
              </div>
            </div>
          </template>
        </iron-pages>
        <!-- /iron-pages Element's-->
      <div class="container flex-center-justified">
        <div>
          <paper-button class="gray" raised>Cancelar</paper-button>
          <paper-button class="gray" raised>Guardar</paper-button>
        </div>
      </div>
    </div>
  </template>
</don-module>

  <script>
    Polymer({

      is: 'protocolo-app',

      properties: {
        protocol: {
          type: String,
          value: ""
        },
        visits:{
          type:Number,
          value: 3,
          notify: true
        },
        tabArray: {
          type: Array,
          value: [{value:"visita1"},{value:"visita2"},{value:"visita3"}]
        },
        tabArrayTest: {
          type: Array,
          value: [{
                    tabName:"visita1",
                    inputs: [{value:"", placeholder:"t1_input1"},{value:"", placeholder:"t1_input2"},{value:"", placeholder:"t1_input3"}]

                  },
                  {
                    tabName:"visita2",
                    inputs: [{value:"", placeholder:"t2_input1"},{value:"", placeholder:"t2_input1"},{value:"", placeholder:"t2_input1"}]
                  },
                  {
                    tabName:"visita3",
                    inputs: [{value:"", placeholder:"t3_input1"},{value:"", placeholder:"t3_input1"},{value:"", placeholder:"t3_input1"}]
                  }]
        },
        selected:{
          type: Number,
          value: 0,
        },
        inputArray: {
          type: Array,
          value: [{value:"",placeholder:"t1_input1"},{value:"",placeholder:"t1_input2"},{value:"",placeholder:"t1_input3"}]
        }
      },

      observers: [
            'test(tabArrayTest.*)'
        ],

      //funcion que agrega input's
      addInput: function(){
        var sel = this.$.selection.value;
        //alert("Tab Seleccionado: " + sel);
        this.push('tabArrayTest.'+ sel + '.inputs',[{value:"",placeholder:""}])[0];
      },
      test: function(){
        console.log("Se modifico el array");
      },
      //funcion que elimina input's
      delInput: function(e){
          var sel = this.$.selection.value;
        this.splice('tabArrayTest.'+ sel + '.inputs',e.model.index,1);
      },
      creaArrayTabs: function(e){
         console.log(this.value);
      },
      concat: function(v1, v2){
        var res = v1 + v2;
        alert("Concatenacion: " + res);
        //return v1 + v2;
      },
      //funcion que carga los arrays necesarios para la aplicacion
      visitChanged: function(e){
        //alert("Valor: " + this.$.visit.value);
        //limpiamos el array para agregar las nuevas tabs
        this.splice('tabArrayTest',e.model);
        //asignamos a la variable max el valor del input
        var max = this.$.visit.value;
        for (i = 0; i < max; i++) { 
          //alert("Prueba " + i);
      var k = i +1;
          this.push('tabArrayTest',{tabName:"Visita " + k, inputs:[{value:"", placeholder:"t"+ k + "_input1"},{value:"", placeholder:"t"+ k + "_input2"},{value:"", placeholder:"t"+ k + "_input3"}]});
          //this['inputArray'+ i] = [];
          //for (j = 0; j < 3; j++) {
          //  this.push('inputArray' + i,{value:"",placeholder:"t"+ i + "_input"+j});
          //}
        }
      }
    });
  </script>