Mike
Mike

Reputation: 768

How to set callback when <template if='...'> is finally instantiated into DOM in Dart Polymer

I have element like that:

<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>

I need to perform some initialization when template with id=="page_template" will be actually instanced into DOM.

I've tried to make something like that:

authenticatedChange(_) {
  if(authenticated)
    shadowRoot.querySelector('#page').addEventListener(...);
}

But got this:

Exception: The null object does not have a method 'addEventListener'

Looks like 'page' just doesn't exists yet. Then I tried to put creation event to the end of event-loop:

authenticatedChange(_) {
  if(authenticated)
    Timer.run(()=>shadowRoot.querySelector('#page').addEventListener(...));
}

This works, but I doubt it is a good style, because there is no guarantee it will actually be created to that step (it's completely implementation-dependent), because no explicit dependency like a Future or callback wasn't binded to event when template is instantiated.

So the question is, does such event exist? All I found was 'template-bound', but this code

$['page_template'].on['template-bound'].listen((_)=>print("template-bound!"));

being executed in MyApp.created(), generates silence in console.

How to bind my code to instantiate/deinstantiate events?

onMutation($['page_template']).asStream().listen((_)=>print("mutated."));

Also didn't work for me.

$['page_template'].shadowRoot is null, so I can't bind to it's mutation at all.

Upvotes: 2

Views: 160

Answers (2)

Jake MacDonald
Jake MacDonald

Reputation: 1348

You could use a mutation observer on your shadow root to do this, add something like the following in your ready method:

new MutationObserver((changes, _) {
    print(changes.any((record) => record.addedNodes.any(
        (node) => node is Element && node.id == 'page')));
})..observe(this.shadowRoot, childList: true);

This will print true any time the page is added. The efficiency of this will clearly vary based on how often your shadow dom is changing. Wrap the template in another node and listen on that if you want to get only the local changes.

Upvotes: 1

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657058

I haven't needed the template-bound event myself yet, but it should be the right approach. If $['page_template'] returns null this code might be in the wrong place. MyApp.created() is the wrong place for most code, especially wrong for everything that is Polymer related. If you override the ready() method and put your code there it should work.

Upvotes: 0

Related Questions