I have a component that looks something like this:
<template>
<template is="dom-if" if="{{userLoggedIn}}">
<div class="logged-in-wrapper" id="loggedInWrapper">
<content></content>
</div>
</template>
<template is="dom-if" if="{{!userLoggedIn}}">
<div class="logged-out-wrapper" id="loggedOutWrapper">
<content></content>
</div>
</template>
</template
In the ready function, this.$ is empty, even though there are two elements that have ids. When I removed the wrapping <template is="dom-if"..., this.$ was populated with the expected ID'd elements. I'm running polymer 1.1.3.
This is a confusing bit for sure
Note: Nodes created dynamically using data binding (including those in dom-repeat and dom-if templates) are not added to the this.$ hash. The hash includes only statically created local DOM nodes (that is, the nodes defined in the element鈥檚 outermost template).
https://www.polymer-project.org/1.0/docs/devguide/local-dom.html#node-finding
basically this is the intended behavior
+1 to further thought around this
If I'm reading it right, I think this is what $$(selector) is good for.
See: https://www.polymer-project.org/1.0/docs/devguide/utility-functions.html
Thanks for the info! Looks like $$(selector) is indeed the workaround, so I will close this ticket.
I spoke too soon. this.$$ is also not working for templates with dom-if.
+1 for making this not the intended behavior as it is misleading.
Grr, you are right, immediately inside ready() it does not ... however ...
these will work:
this.querySelector('#myID');
this.$$('#myID');
if you put them in an async like:
this.async(function(){
this.querySelector('#myID');
this.$$('#myID');
}.bind(this), 50);
Ah okay, that does seem to work. Going to leave this ticket open though b/c this seems like an okay work-around but not an ideal scenario.
Thanks again!
Agreed +1
Also, I would like to know the definition of ready() as it pertains to nested templates.
I reread this: https://www.polymer-project.org/1.0/docs/devguide/registering-elements.html#ready-method but I don't see any information specific to this.
Are these nested templates considered local DOM or light DOM?
Any DOM defined in your <dom-module>'s <template> is local DOM to that element. It's the element's shady/shadow dom.
ready() is a lifecycle method that signifies when your element's shady/shadow dom has been created, properties init'd, etc.
The problem here is that content inside a <template if> is inert until it's stamped and Polymer cannot see content inside the template until that happens. DOM manipulations happen at the end of a microtask, at the end of property changes. That's why you need to wait a tick (this.async) for the <template if> to have stamped its content. If you're doing this on page load, you could try:
ready: function() {
this.async(function() {
...
});
}
@ebidel Thanks for making that clear :)
Most helpful comment
Any DOM defined in your
<dom-module>'s<template>is local DOM to that element. It's the element's shady/shadow dom.ready()is a lifecycle method that signifies when your element's shady/shadow dom has been created, properties init'd, etc.The problem here is that content inside a
<template if>is inert until it's stamped and Polymer cannot see content inside the template until that happens. DOM manipulations happen at the end of a microtask, at the end of property changes. That's why you need to wait a tick (this.async) for the<template if>to have stamped its content. If you're doing this on page load, you could try: