如何从模板元素中获取子元素?

时间:2017-02-22 21:20:04

标签: polymer polymer-1.0

dom-change中的

Polymer.dom(e).localTarget事件对象e为我提供了<template is="dom-if"。但是如何访问孩子<div id="uploadedImage1"firstChildfirstElementChild为空。

  <template is="dom-if" if="[[uploadedImage1]]">
    <div id="uploadedImage1" class="row-image horizontal layout">
      foo
    </div>
  </template>

我想也许我需要从localTarget对象做另一个查询但没有成功:

    this.$['images-container'].addEventListener('dom-change', (e)=> {
      var bob = Polymer.dom(e).localTarget;
      var sue = Polymer.dom(bob).querySelector('div')
      console.log(sue);
    });

我也试过这些没有成功:

    this.$['images-container'].addEventListener('dom-change', (e)=> {
      var bob = Polymer.dom(e).localTarget;
      var sue = this.queryEffectiveChildren(bob);
      console.log(sue);
    });
    this.$['images-container'].addEventListener('dom-change', (e)=> {
      var bob = Polymer.dom(e).localTarget;
      var sue = bob.getEffectiveChildNodes();
      console.log(sue);
    });
  }

来自children length documentation example,偶数Polymer.dom(this).children.length返回0:

<dom-module id="image-uploader">
  <template>
    <style include="iron-flex iron-flex-factors iron-flex-alignment">


    <div id="images-container" class="horizontal layout center wrap">

      <div hidden="[[uploadedImage1]]" class="layout vertical center-center">
        <div class="row-image horizontal layout">
          <input
            type="file"
            name="file"
            data-uploaded="uploadedImage1"
            id="image1"
            accept="image/jpeg"
            class="inputfile" />
          <label
            for="image1"
            id="image1"
            class="image-show horizontal layout center center-justified">
            <iron-icon icon="add" prefix></iron-icon>
            Upload Image
          </label>
        </div>
        <i>*Main Image</i>
      </div>

      <template is="dom-if" id="foo" if="[[uploadedImage1]]">
        <div id="uploadedImage1">
          foo
        </div>
      </template>

    </div>

  </template>

  <script>
    Polymer({
      is: 'image-uploader',
      properties: {
        uploadedImage1: {
          type: Boolean,
          value: false
        }
      },
      ready: function(e) {
          console.log(Polymer.dom(this).children.length);

2 个答案:

答案 0 :(得分:4)

我看到了一些问题,所以我将通过它们进行讨论并最后给出一个有效的例子。

了解template

<div id="uploadedImage1" ...元素可以而且永远不会是dom-if模板的子元素。就组件的本地DOM而言。

根据W3C Living Documenttemplate标记定义了一个标记块(称为DocumentFragment),它在主文档中实际上不存在,并且可以在运行时克隆并放入Document中。它不包含任何呈现的标记,因此您无法向template询问文档其余部分中使用的内容。

为了说明一个真实的例子,考虑一个橡皮图章(模板)和一张纸(文件)。如果您将印章压印在纸上一次或多次,则无法查看橡皮图章并知道它在纸张上标记的图像的位置,位置或次数。要获得这些信息,您必须查看论文本身。

如果在模板周围添加容器元素并将其记录到控制台,您将从Document透视图中清楚地看到它的外观:

<div id="container" class="style-scope my-el">
  <div id="uploadedImage1" class="style-scope my-el">
    foo
  </div>
  <template is="dom-if" id="foo" class="style-scope my-el"></template>
</div>

了解dom-change事件背景

您有合理的想法使用Polymer的DOM方法来查找所需的元素,但是在所有尝试中,您都要从事件目标的上下文开始,这是模板。

同样,模板实际上并不包含您要查找的元素,因此您永远不会在此处找到它。

了解Polymer的DOM基础知识

您引用的文档用于访问标记为<container>的Light DOM儿童。在您的情况下,您不会将任何轻型DOM子项标记到元素shadow DOM中。您正在使用dom-if模板根据状态有条件地显示/隐藏内容。

解决方案

只需要求组件使用$$简写方法在组件的本地DOM中查找元素,即可实现所需。需要考虑的一件事是出于性能原因,一旦条件变得真实,Polymer会对dom-if模板的内容进行标记,然后使用CSS来显示和隐藏它,因此可能是模板在DOM中但是没有显示。

以下是一个工作示例的摘录(请参阅fiddle),它通过让dom-change侦听器访问组件对象(通过bind())来实现您的目标,因此它可以a)访问组件的本地DOM以查找元素,b)考虑dom-if条件是否真实。

this.$.foo.addEventListener('dom-change', function() {
  if (this.prop1) {
    console.log(this.$$('#uploadedImage1'));
  } else {
   console.log(null);
  }
}.bind(this));

答案 1 :(得分:0)

Polymer.dom(e).localTarget.content可让我访问documentFragment,至少可以在Chrome上使用。