在自定义元素中,我想访问span
并向其添加子项,但所有常用访问者都会undefined
:
<template>
<template is="dom-if" if="[[condition]]" restamp>
<span id="myspan"></span>
</template>
</template>
ready() {
var a = this.$.myspan; //<------- is undefined
var b = this.$$.myspan; //<------- is undefined
var c = document.getElementById("myspan"); //<------- is undefined
var d = this.$$("#myspan"); //<------- is undefined
}
在这种情况下如何访问span
?
更新:此处为plunk
答案 0 :(得分:5)
这个在没有setTimeout或this.async的生命周期回调中不起作用的原因是在附加你的元素之后dom-if模板还没有渲染。附加元素后,Polymer会调用附加的回调函数。但是,当在dom-if上设置值时,观察者会运行并去抖它自己的_render函数。 debounce等待一段时间来捕获对它的任何其他调用,然后它执行._render函数并将元素附加到DOM。换句话说,当附加的回调运行时,通常dom-if模板还没有渲染。
这次去抖的原因是表现。如果在很短的时间内进行了多次更改,那么当我们关心的结果是最终结果时,这种去抖动会阻止模板多次渲染。
幸运的是,dom-if提供了一个.render()方法,允许你同步渲染。你需要做的就是为你的dom-if添加一个id,切换到附加的回调和这样打电话:
<template>
<template id="someDomIf" is="dom-if" if="[[condition]]" restamp>
<span id="myspan"></span>
</template>
</template>
attached() {
this.$.someDomIf.render();
var c = document.getElementById("myspan"); //<------- should be defined
var d = this.$$("#myspan"); //<------- should be defined
}
在dom-if上触发同步渲染不应该是一个巨大的性能问题,因为幸运的是你的元素应该只被连接一次。 修改:当它转过来时,这个甚至就可以在准备好的回调中工作:
<template>
<template id="someDomIf" is="dom-if" if="[[condition]]" restamp>
<span id="myspan"></span>
</template>
</template>
ready() {
this.$.someDomIf.render();
var c = document.getElementById("myspan"); //<------- should be defined
var d = this.$$("#myspan"); //<------- should be defined
}
查看你的plunker的这个叉子: http://plnkr.co/edit/u3richtnt4COpEfx1CSN?p=preview
答案 1 :(得分:1)
尝试在附加方法中异步执行此操作,如下所示:此方法有效:
attached: function(){
this.async(function(){
var d = this.$$("#myspan");
console.log(d);
},someTimeIfThereAreManyItemsToLoad);
}
答案 2 :(得分:0)
上述答案仅在最初条件为真时才有效。请查看我对您的初始问题的回答: https://stackoverflow.com/a/34137955/3085985
不确定你是否应该混合来自Dogs的.render-stuff,但我仍然认为观察者将是适合它的地方,因为如果条件最初是假的,它将不起作用。
答案 3 :(得分:0)
与Polymer文档中一样:
注意:使用数据绑定动态创建的节点(包括
dom-repeat
和dom-if
模板中的节点)不会添加到this.$
哈希中。哈希仅包含静态创建的本地DOM节点(即元素最外层模板中定义的节点)。
您需要使用this.$$('#yourElementId");