[ engine demonstrations | engine overview | imnmotion.com | Stephen W. Cote ]
Demonstration #18 builds on the template and embedded-script features introduced by Demonstration #17. This demonstration shows how embedded-script elements are used to extend an application component for the lifespan of a loaded template. Also, this demonstration shows how the component is automatically transformed into an Engine, which gives it additional flexibility including using predefined object constructs such as import-xml (refer Demonstration #3), as well as the automatic persistence of form values as the form elements are created, destroyed, and recreated. This makes it easy to collect information from multiple templates, validate the field values, and then reference the field values long after the original form elements were destroyed.
A Note About Browser Support: Many demonstrations, including this one, use the EngineService module of Engine for Web Applications, which relies to some degree on XPath. Some browsers, including Opera up to 8.5, and Safari up to 1.3, do not support XPath and therefore the module will not operate. The EngineService module is entirely optional and is used in the demonstrations for its convenience.
Starting Engine
The application compnonent used in this example is largely superfluous, and this example could be created without the external component. The two things to note are how the component is instructing itself to treat templates like Engines, and then loading a template specified on an attribute.
<application-component id = "TemplateDemo"><![CDATA[
component_init : function(){
this.setTemplateIsEngine(1);
this.loadTemplate(this.getContainer().getAttribute("template"));
}
]]></application-component>
The template file is XHTML, using the ${this} keyword discussed in Demonstration #17, and also using an Engine construct, import-xml, to load additional embedded script and XHTML. The important thing to note is that the embedded_init function is scoped to the embedded-script statements, so that multiple declarations may be made. This allows imported template fragments to easily latch onto the initialization state of the template, much in the same way as the template_init function.
<Template>
<input type = "text" rid = "TestText" />
<input type = "button" value = "Next" onclick = "${this}.Next()" />
<import-xml src = "DemoImport.xml" />
<embedded-script><![CDATA[
Next : function(){
// invoking loadTemplate is all that is necessary to move on to another
// set of content
//
this.loadTemplate(...);
},
// invoked when template is loaded.
// there can only be one instance of this function
// for a template
//
template_init : function(){
this.CallImportedFunction();
},
// invoked when template is loaded
// there can be one instance per embedded-script element
//
embedded_init : function(){
},
// invoked when template is unloaded
// there can be one instance per embedded-script element
//
embedded_destroy : function(){
},
]]></embedded-script>
</Template>
In this example, note that the first template references the function defined in the second. These functions are context sensitive to the component, and are automatically removed when the template changes. This has positive and negative connotations: any references to embedded-script functions that are held as pointers should be cleaned up in the template_destroy or embedded_destroy functions.
<Template>
<embedded-script><![CDATA[
CallImportedFunction : function(){
},
// invoked when template is loaded
// there can be one instance per embedded-script element
//
embedded_init : function(){
},
]]></embedded-script>
</Template>