简体   繁体   中英

Polymer 2.0 Access Element Inside of Nested Template by Id

Polymer provides access to elements by id via this.$['foo']. However, I find that I am unable to access elements by id that are in nested templates.

<template>
     <vaadin-dialog id="dialog" >
          <template>
     <work-order-new  id="workordernew" on-submitted="_onWorkOrderSubmitted"> </work-order-new>
          </template>
     </vaadin-dialog>
    </template>

In this situation this.$.dialog works but this.$.workordernew does not. Are you able to access elements inside of a nested template by id and if so how?

I also tried both of approches below and they also didn't work .

Polymer.dom(this.root).querySelector():

this.$$(selector)

I saw a lot of answers for this question but none of them solved my problem.

The issue you're facing is not strictly a Polymer issue, but more a reflection of what Vaadin is doing behing the scenes.

When the vaadin-dialog element is created the actual contents of the template are copied in an other element - vaadin-dialog-overlay - rather than staying in the original element.

The overlay element is inserted at the document level, so you can grab it querying for it:

let vaadinOverlay = document.querySelector('vaadin-dialog-overlay');

Once you have the overlay it's easy to get to your work-order-new element:

let workOrder = vaadinOverlay.$.content.querySelector('#workordernew');

The real question would be in this case: why are you trying to access your elements directly?

Usually, when working with components, getting to the point when you need to directly access a component is usually a good indication that there is something broken in the design of the application.

 <base href="https://polygit.org/vaadin-dialog+vaadin+v1.0.0-alpha1/vaadin-button+vaadin+v1.0.0-alpha1/polymer+^2.0.0/components/"> <script src="webcomponentsjs/webcomponents-lite.js"></script> <link rel="import" href="vaadin-dialog/vaadin-dialog.html"> <link rel="import" href="vaadin-button/vaadin-button.html"> <my-element></my-element> <dom-module id="my-element"> <template> <vaadin-dialog opened> <template> <work-order-new id="workorder"></work-order-new> </template> </vaadin-dialog> </template> </dom-module> <dom-module id="work-order-new"> <template> <h4>Work Order</h4> <input type="text" id="inputbox" value="Default Value"> </template> </dom-module> <script> // Extend Polymer.Element base class class MyElement extends Polymer.Element { static get is() { return 'my-element'; } constructor() { super(); } connectedCallback() { super.connectedCallback(); /** * Fetch the reference to the overlay. **/ let vaadinOverlay = document.querySelector('vaadin-dialog-overlay'); /** * Fetch the reference to the `work-order-new` element. **/ let workOrder = vaadinOverlay.$.content.querySelector('#workorder'); /** * Wait for the overlay to be setup, this is just to show * that we can now use the reference to the `work-order-new` * element. **/ setTimeout(() => { let inputBox = workOrder.$.inputbox; inputBox.value = `Changed from my-element`; }, 1500); } } customElements.define(MyElement.is, MyElement); class WorkOrderNewElement extends Polymer.Element { static get is() { return 'work-order-new'; } constructor() { super(); } connectedCallback() { super.connectedCallback(); } } customElements.define(WorkOrderNewElement.is, WorkOrderNewElement); </script> 

In Polymer 3 , this is can be done like this

let vaadinOverlay = document.querySelector('vaadin-dialog-overlay');
let workorder = vaadinOverlay.$.content.shadowRoot.querySelector('#workorder');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM