【问题标题】:Polymer 2.0 Access Element Inside of Nested Template by Id嵌套模板内的 Polymer 2.0 访问元素(按 Id)
【发布时间】:2018-09-12 18:24:49
【问题描述】:

Polymer 通过 this.$['foo'] 按 id 提供对元素的访问。但是,我发现我无法通过 id 访问嵌套模板中的元素。

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

在这种情况下 this.$.dialog 有效,但 this.$.workordernew 无效。您是否可以通过 id 访问嵌套模板中的元素?如果可以,如何访问?

我也尝试了以下两种方法,但它们也不起作用。

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

this.$$(选择器)

我看到了很多关于这个问题的答案,但没有一个能解决我的问题。

【问题讨论】:

  • 为什么需要访问它?如果要在父元素和子元素之间发送数据,请使用 propertiesnotify: true。否则,请使用事件 (this.fire()) 和侦听器。

标签: javascript html polymer vaadin polymer-2.x


【解决方案1】:

您面临的问题并非严格意义上的聚合物问题,而更多地反映了 Vaadin 在幕后所做的事情。

vaadin-dialog 元素被创建时,模板的实际内容被复制到另一个元素 - vaadin-dialog-overlay - 而不是保留在原始元素中。

覆盖元素插入document 级别,因此您可以抓取它进行查询:

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

一旦你有了覆盖,就很容易找到你的work-order-new元素:

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

在这种情况下,真正的问题是:您为什么要尝试直接访问您的元素?

通常,在使用组件时,到达需要直接访问组件的地步通常是一个很好的迹象,表明应用程序的设计存在问题。

<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>

【讨论】:

  • 但是这个来自 Polymer 1.0
  • 没有任何关于“模板中的模板”站的示例或信息。我阅读了这些文档。
  • 更新了答案,解释了您所看到的行为和一个示例 - 使用与您的 sn-p 类似的设置 - 以显示如何访问该元素。
【解决方案2】:

在 Polymer 3 中,可以这样做

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 2017-07-20
    • 2021-07-09
    相关资源
    最近更新 更多