Multiple instances of the same polymer element cause behavior on all

I have this simple element that allows you to simultaneously select a local file and then display the selected files as elements that you can delete, for example: enter image description here

The component itself works very well, the problem is that I have another component of the same type inside the same page, but inside another parent element (and hidden). If I select n files in this first file selector, then switch to viewing another parent component, this second file selector will display the same files in it as in the first one.

If I put two of these file components in the same parent, selecting a file in one of them does not display the same file in the other, but deleting the file from any of them makes the property of the component file array (where I store each selected file) shorter in both of them, which ultimately leads to the inability to remove elements from one of them.

I believe that my problem is related to encapsulation in some way, but cannot understand why. This is my component code:

<dom-module id="custom-file-input"> <style> ... </style> <template> <div class="horizontal layout flex relative"> <button class="action" on-click="butclick" disabled$="{{disab}}">{{restexts.CHOOSEFILE}}</button> <div id="fakeinput" class="flex"> <template is="dom-repeat" items="{{files}}" as="file"> <div class="fileitem horizontal layout center"> <span>{{file.0}}</span><iron-icon icon="close" class="clickable" on-click="removeFile"></iron-icon> </div> </template> </div> <input id="fileinput" type="file" on-change="fileChanged" hidden /> </div> </template> <script> Polymer({ is: "custom-file-input", properties: { files: { type: Array, value: [] }, currentFile: { type: Object, value: {} }, disab: { type: Boolean, value: false, reflectToAttribute: true, notify: true }, restexts: { type: Object, value: JSON.parse(localStorage['resourcesList']) } }, fileChanged: function (e) { this.currentFile = e.currentTarget.files[0]; var elem = this; var fr = new FileReader(); fr.readAsArrayBuffer(this.currentFile); fr.onload = function () { [...convert file to string64...] elem.push('files', [elem.currentFile.name, string64]); }; }, removeFile: function (e) { for (var i = 0; i < this.files.length; i++) { if (this.files[i] == e.model.file) { this.splice('files', i, 1); break; } } }, butclick: function () { this.$.fileinput.click(); } }); </script> </dom-module> 
+5
source share
1 answer

When initializing a property for an object or array value, use a function to ensure that each element gets its own copy of the value , instead of having the object or array shared in all instances of the element.

Source: https://www.polymer-project.org/1.0/docs/devguide/properties.html#configure-values

 { files: { type: Array, value: function() { return []; } }, currentFile: { type: Object, value: function() { return {}; } }, restexts: { type: Object, value: function() { return JSON.parse(localStorage['resourcesList']); } } } 
+9
source

All Articles