Code for a very small app illustrating these multiple constructor calls is now up on GitHub at https://github.com/Chiba-City/testnest.
I am trying to figure out
- why a polymer element would be constructed twice and
- what determines the order of construction of polymer elements that contain other polymer elements and
- why is a "templated out" element using an "if" template constructed at all.
Also, if one cannot reproduce these results with three simple polymer elements, one defined to contain or nest the other two, I would also love to know that as well.
I am finding duplicate constructor calls and constructor ordering peculiarities. Here is an explanation of the occurrence of these peculiarities.
I have a very simple "app". There is an index.html file that html-includes a file of custom element definitions and declares just one custom polymer-dart element in its body. Here are the relevant portions of the index.html file. I have elided the customary boiler plate.
<!-- index.html -->
<!-- in head -->
<link rel="import" href="icapp.html">
<!-- boiler plate polymer/init.dart and ../dart.js stuff here -->
<!-- only contents of body tag -->
<icount-app></icount-app>
Now in "icapp.html" I define two elements consisting only of h3 labels. I contain these two elements in the template for a third element which begins with a simple H1 label. Here is the code for all three elements.
<!-- icapp.html -->
<!-- User stats list -->
<polymer-element name="icount-statlist" >
<template><h3>My Stats</h3></template>
</polymer-element>
<!-- Find stats -->
<polymer-element name="icount-findstats" >
<template><h3>Find New Stats</h3></template>
</polymer-element>
<!-- This is the element that contains the other two elements in its template -->
<polymer-element name="icount-app">
<template>
<h1>icount.us</h1> <!-- a simple h1 heading -->
<!-- Included always -->
<icount-findstats></icount-findstats>
<!-- Included conditionally - but can never be true -->
<template if="{{false}}">
<icount-statlist ></icount-statlist>
</template>
<!-- End icount-app template -->
</template>
<!-- The code with the element definitions -->
<script type="application/dart" src="icapp.dart"></script>
</polymer-element>
I have put "print" statements in the ".created() : super.created" constructors as well as overriden "enteredView()" methods to determine the order and frequency of these calls. Here is the output during execution. I have added notes prefixed with "--"
-- note this is first, although conditional on {{false}}
IcountStatlist: created
-- now the containing element is constructed
IcountApp: created
-- notice that enteredView happens before the nested element
IcountApp: enteredView
-- notice that this element is constructed twice
IcountFindstats: created
IcountFindstats: created
IcountFindstats: enteredView
The output of the application is as expected (H1 and an H3 tags, the latter for the non-conditionally included "icount-findstats" element). But how it arrives here is peculiar, and in ways that would seem to defy adding reasonable program logic to these tags (properties, event handlers and so on).
- The visible nested element is constructed twice
- The "templated out" nested element is constructed once
- The visible nested element's "enteredView" method is called (not surprisingly).
Above the contained visible element is constructed after the containing element. But simple experimentation shows that this ordering seems arbitrary, or at least, not dependent on templating or ordering of nested elements.
If we simply switch our preference for which nested element we "template out" we get the following output instead.
IcountStatlist: created
IcountStatlist: created
IcountStatlist: enteredView
IcountApp: created
IcountApp: enteredView
IcountFindstats: created
Here we can note:
The visible nested element, this time icount-statlist, is constructed twice, as above, but created before the containing element. Also the HTML output h3 tag occurs only once.
This visible nested element's "enteredView" method is called prior to the containing element.
The "templated out" nested element is again created (just once), but now after the containing element.
Further experimentation shows that the same element non-conditionally, visibly nested twice results in 4 constructor calls (for that element).
Another experiment shows that the same element conditionally contained twice results in 2 constructor calls (for that element).
Experimenting with reordering the "templated out" element and the visible element reveals no change in log output, i.e., the order or frequency of constructor calls.
Needless to say, I am perplexed.
Why is the visible nested element constructed twice ?
Why is the "templated out" nested element constructed at all ?
Why is one nested element constructed before the containing element and the other after ?
Why is the containing element, icount-app, itself not constructed twice?
How can a containing element sensibly set properties of contained elements given nature and ordering of custom polymer element (object) construction?
Any help greatly appreciated.