<template if='...'> 在 Dart Polymer 中最终实例化为 DOM 时如何设置回调
How to set callback when <template if='...'> is finally instantiated into DOM in Dart Polymer
我有这样的元素:
<polymer-element name="my-app">
<template>
<template id="page_template" if="{{authenticated}}">
<my-page id="page"></my-page>
</template>
</template>
<script src="..."></script>
</polymer-element>
当 id=="page_template" 的模板实际实例化到 DOM.
时,我需要执行一些初始化
我试过做类似的东西:
authenticatedChange(_) {
if(authenticated)
shadowRoot.querySelector('#page').addEventListener(...);
}
但是得到了这个:
Exception: The null object does not have a method 'addEventListener'
看起来 'page' 还不存在。
然后我尝试将创建事件放到事件循环的末尾:
authenticatedChange(_) {
if(authenticated)
Timer.run(()=>shadowRoot.querySelector('#page').addEventListener(...));
}
这行得通,但我怀疑它是不是一个好的样式,因为不能保证它实际上会被创建到那个步骤(它完全依赖于实现),因为没有像 Future 或回调这样的显式依赖实例化模板时绑定到事件。
那么问题来了,这样的事件存在吗?我找到的只是 'template-bound',但是这段代码
$['page_template'].on['template-bound'].listen((_)=>print("template-bound!"));
在 MyApp.created() 中执行,在控制台中产生静默。
如何将我的代码绑定到 instantiate/deinstantiate 事件?
onMutation($['page_template']).asStream().listen((_)=>print("mutated."));
我也没用。
$['page_template'].shadowRoot
是 null
,所以我根本无法绑定到它的突变。
我自己还不需要 template-bound
事件,但这应该是正确的方法。如果 $['page_template']
returns null
此代码可能在错误的位置。 MyApp.created()
是大多数代码的错误位置,尤其是与 Polymer 相关的所有代码。如果您覆盖 ready()
方法并将您的代码放在那里它应该可以工作。
您可以在影子根上使用变异观察器来执行此操作,在您的 ready
方法中添加如下内容:
new MutationObserver((changes, _) {
print(changes.any((record) => record.addedNodes.any(
(node) => node is Element && node.id == 'page')));
})..observe(this.shadowRoot, childList: true);
这将在添加页面时打印 true
。这样做的效率显然会根据阴影 dom 变化的频率而有所不同。如果您只想获取本地更改,请将模板包装在另一个节点中并监听它。
我有这样的元素:
<polymer-element name="my-app">
<template>
<template id="page_template" if="{{authenticated}}">
<my-page id="page"></my-page>
</template>
</template>
<script src="..."></script>
</polymer-element>
当 id=="page_template" 的模板实际实例化到 DOM.
时,我需要执行一些初始化我试过做类似的东西:
authenticatedChange(_) {
if(authenticated)
shadowRoot.querySelector('#page').addEventListener(...);
}
但是得到了这个:
Exception: The null object does not have a method 'addEventListener'
看起来 'page' 还不存在。 然后我尝试将创建事件放到事件循环的末尾:
authenticatedChange(_) {
if(authenticated)
Timer.run(()=>shadowRoot.querySelector('#page').addEventListener(...));
}
这行得通,但我怀疑它是不是一个好的样式,因为不能保证它实际上会被创建到那个步骤(它完全依赖于实现),因为没有像 Future 或回调这样的显式依赖实例化模板时绑定到事件。
那么问题来了,这样的事件存在吗?我找到的只是 'template-bound',但是这段代码
$['page_template'].on['template-bound'].listen((_)=>print("template-bound!"));
在 MyApp.created() 中执行,在控制台中产生静默。
如何将我的代码绑定到 instantiate/deinstantiate 事件?
onMutation($['page_template']).asStream().listen((_)=>print("mutated."));
我也没用。
$['page_template'].shadowRoot
是 null
,所以我根本无法绑定到它的突变。
我自己还不需要 template-bound
事件,但这应该是正确的方法。如果 $['page_template']
returns null
此代码可能在错误的位置。 MyApp.created()
是大多数代码的错误位置,尤其是与 Polymer 相关的所有代码。如果您覆盖 ready()
方法并将您的代码放在那里它应该可以工作。
您可以在影子根上使用变异观察器来执行此操作,在您的 ready
方法中添加如下内容:
new MutationObserver((changes, _) {
print(changes.any((record) => record.addedNodes.any(
(node) => node is Element && node.id == 'page')));
})..observe(this.shadowRoot, childList: true);
这将在添加页面时打印 true
。这样做的效率显然会根据阴影 dom 变化的频率而有所不同。如果您只想获取本地更改,请将模板包装在另一个节点中并监听它。