how to dynamically append an element to dom-if in

2019-02-23 12:08发布

问题:

My goal is to append an element to existing dom-if dynamically. Problem is that after appending I can see appended element in the DOM three but it never reacts on condition and stays always hidden.

<template>
    <template id="domif" is="dom-if" if="[[condition]]" restamp></template>
</template>

ready() {
    var el = document.createElement("input");
    Polymer.dom(this.$.domif).appendChild(el);
    Polymer.dom.flush();
}

Exploring DOM with hardcoded dom-if and input shows that <input /> element is actually not a child of dom-if but lives next to it..

<template>
    <template is="dom-if" if="[[condition]]" restamp>
       <input />
    </template>
</template>

That gave me a clue that I probably should append my element next to dom-if... But now the biggest question is how to say to dom-if that appended element should be rendered if condition is satisfied. Any ideas?

回答1:

How about adding a span in your dom-if and appending it to that span?

Update after some comments : We need to use this.async for the item to be found. Using the ready-event only works when the condition is true initially. So you could append the element in a conditionChanged-observer - this is a working example :

<dom-module id='my-element1'>
  <template>
    <template is="dom-if" if="[[condition]]" restamp>
      <span id="appendHere"></span>
    </template>
  </template>
</dom-module>

<script>
  Polymer({
    is: 'my-element1',
    properties: {
      condition: {
        type: Boolean,
        observer: "_conditionChanged"
      }
    },
    _conditionChanged: function(newVal) {
      if (newVal) {
        this.async(function() {
          var el = document.createElement("input");
          Polymer.dom(this.$$("#appendHere")).appendChild(el);
          Polymer.dom.flush();
        });
      }
    }
  });
</script>

Try it here : http://plnkr.co/edit/1IIeM3gSjHIIZ5xpZKa1?p=preview .

A side-effect of using dom-if in this case is that after setting the condition to false, the element disappears completely and gets added on the next condition-change again. So every change before setting the condition to false gets lost. You could work around it by putting the added element somewhere hidden when the condition changes and getting it back later, but I don't think this is a good idea, if the following is an alternative :

The Polymer-team recommends using dom-if only if there is no other way, like hiding the element. So, if it is possible you also could do something like this (condition has to be true to hide the element) :

<dom-module id='my-element1'>
  <template>
    <span id="appendHere" hidden$="[[condition]]"></span>
  </template>
</dom-module>

<script>
  Polymer({
    is: 'my-element1',
    properties: {
      condition: Boolean
    },
    ready: function() {
        var el = document.createElement("input");
        Polymer.dom(this.$.appendHere).appendChild(el);
        Polymer.dom.flush();
    }
  });
</script>

Try it here : http://plnkr.co/edit/mCtwqmqtCPaLOUveOqWS?p=preview



回答2:

The template element itself will not be added to the DOM, this is the reason you can't access it using querySelector or getElementXxx