【问题标题】:Polymer 2 access file uploaded in another pagePolymer 2 访问文件上传到另一个页面
【发布时间】:2018-11-13 19:34:21
【问题描述】:

我正在使用一个简单的聚合物应用程序,在铁页中只有几页。我正在一个页面中上传一个文件,然后我想在另一个页面中访问这个上传的文件。

我尝试了几件事,但似乎没有任何效果,这是示例代码

上传文件的页面

<dom-module id="file-upload-page">
    <template>
        <form method="post" enctype="multipart/form-data" action="/someation" disable-native-validation-ui no-validate>
            <my-input file={{file}} id="sampleFileInput" btn-style="primary" max-files="1" accept=".xls, .xlsx" on-drop="fileUploadChangeListener"
                label="[[localize('open_invoices_file')]]" help-text="[[localize('open_invoices_file_help')]]" no-auto required>
            </my-input>
        </form>
    </template>
    <script>
        class FileUploadPge extends Polymer.mixinBehaviors([], Polymer.Element) {
            static get is() {
                return 'file-upload-page';
            }

            static get properties() {
                return {
                }
            }
         }

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

访问文件的页面

<dom-module id="consumer-page">
    <template>
        //some code
    </template>

    <script>
        class ConsumerPage extends Polymer.mixinBehaviors([], Polymer.Element) {

            static get is() {
                return 'consumer-page';
            }

            constructor() {
                super();
            }

            static get properties() {
                return {
                    //some properties
                }
            }

            ready() {
                super.ready();
                var temp2 = this.$.sampleFileInput;   // returns null
                var temp3 = this.shadowRoot.querySelector("#sampleFileInput"); // returns null
                var temp4 = this.root.querySelector('#sampleFileInput'); // returns null
                var temp5 = this.$$('#sampleFileInput'); // returns null
                this._refreshSelections();

            };

            _proceed() {

                var test1 = Polymer.dom(this).querySelector("#sampleFileInput"); // returns null
                var test2 = this.$.sampleFileInput; //returns null
                var test3 = document.getElementById("sampleFileInput"); //returns null
                var test4 = this.$$("sampleFileInput"); //returns null
                var test5 = this.shadowRoot; //returns some object


                var test6 = this.$$.sampleFileInput; //returns null
                var test7 = document.querySelector('sampleFileInput'); //returns null
                var test8 = document.querySelector('file-upload-page::shadow .FileUploadPge'); //returns null
                var temp4 = this.root.querySelector('#sampleFileInput');//returns null
                var temp5 = this.$$('#sampleFileInput');//returns null
                var temp6 = this.shadowRoot.querySelector('#sampleFileInput'); // returns null
            };
        }

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

相同的代码在polymer1.0 中使用这个

document.getElementById("sampleFileInput")

有人可以帮助我在其他页面中访问此文件时做错了什么,以及如何在 Polymer 2.0 中处理这种情况?

【问题讨论】:

  • Polymer 2 默认为 Shadow DOM(与 Polymer 1 中的 ShadyDOM 默认设置相反)。您使用的查询选择器不会深入到 Shadow DOM 中的子元素。我猜&lt;consumer-page&gt; 包含一个&lt;file-upload-page&gt; 元素,而&lt;consumer-page&gt; 正试图获取对&lt;file-upload-page&gt; 内部元素的引用。对吗?

标签: polymer polymer-2.x shadow-dom


【解决方案1】:

正如您在consumer-page 中所说,您正在尝试访问#sampleFileInput 元素,它是另一个组件的子元素。

所有这些尝试:

var temp2 = this.$.sampleFileInput;
var temp3 = this.shadowRoot.querySelector("#sampleFileInput"); 
var temp4 = this.root.querySelector('#sampleFileInput');
var temp5 = this.$$('#sampleFileInput');
var test1 = Polymer.dom(this).querySelector("#sampleFileInput");

失败,因为您试图访问consumer-page 的模板中不存在的元素,而这些:

var test7 = document.querySelector('sampleFileInput');
var test8 = document.querySelector('file-upload-page::shadow .FileUploadPage');

分别失败是因为document.querySelector() 无法在shadow dom 内部选择,并且::shadow/deep/ 选择器已被弃用(see here)。

从技术上讲,您应该可以通过这种方式在consumer-page 中选择#sampleFileInput

this.parentElement // Goes back to iron-pages
    .querySelector('file-upload-page') // Selects file-upload-page
    .shadowRoot // Enters its shadow root
    .querySelector('#sampleFileInput'); // Selects the file uploader

但是,访问其他人的影子根中的元素被认为是 not so good practice,更不用说如果您对 iron-pages 页面使用延迟加载,如果未加载 file-upload-page,这将失败。

还有许多其他方法可以在自定义元素(例如事件或属性)之外公开​​信息。
如果它适合您的实现,您可以使用持有 iron-pages 的组件作为您的过程的协调器,并使用属性绑定来通知它,当用户继续填写时,它需要来自不同页面的数据。

file-upload-page中的IE将上传的文件url绑定到一个属性,在parent中观察:

<iron-pages>
    <file-upload-page url="{{url}}"></file-upload-page>
    <consumer-page></consumer-page>
</iron-pages>

<script>
    class Parent extends PolymerElement {

        // ...

        static get properties() {
            return {
                url: {
                    type: String,
                    reflectToAttribute: true,
                    observer: '_urlChanged',
                },
            };
        }

        _urlChanged() {
            console.log(this.url);
        }

        // ...
    }
</script>

【讨论】:

  • 感谢 Umbo,它的完整答案,它解决了问题并阐明了概念
  • Umbo 我喜欢你的第二种方法,但这是我的场景,我正在上传一个文件,共享 url 将如何帮助,我不应该共享文件对象本身(因为文件已经上传到另一页)。我在这种方法中有什么遗漏吗?
  • 当然这取决于您的需求,url 只是一个示例。所以你需要上传后的整个文件内容吗?
  • 您可以尝试与url 相同的操作,将整个内容(我猜是String,我猜?)传递给属性或CustomEventdetail
猜你喜欢
  • 1970-01-01
  • 2010-12-27
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 2019-03-16
  • 1970-01-01
相关资源
最近更新 更多