Appendix A. Understanding Instantiation

Table of Contents

1. Overview
2. When instances are instantiated
3. How instances are instantiated

1. Overview

The instantiation of lz.node objects such as lz.view and lz.layout is a multi-phase procedure, but in general, you do not need to know the details of the instantiation of view objects; they "just work". In rare cases, you will need to understand the details of the process. Parts of the process can be deferred to speed startup of an application.

This chapter assumes you are familiar with classes and objects. In the descriptions below, we distinguish between construction, by which we mean storage for the object is allocated and constant properties assigned (a process that cannot be customized) and initialization, by which we mean the instantiation of children and the application of constraints and computed attributes, which can be customized (by overriding the init() method). These two processes together are referred to as instantiation.

2. When instances are instantiated

At a high level, the initialization of a lz.node, the calling of its init() method, and sending of the oninit() event is under the control of its initstage attribute, as follows:

Table A.1. When instances are instantiated

Value Definition
immediate Initialization happens immediately as the last stage of instantiation.
early Initialization happens right after the view and its children have been created.
normal Initialization happens when the parent is initialized.
late Initialization happens during idle time. To check whether the view has been initialized, check the isinited property. Force initialization using the completeInstantiation() method.
defer Initialization will not happen unless explicitly requested by calling the completeInstantation() method.

3. How instances are instantiated

When a node is instantiated, its attributes are the attributes explicitly given in the object, plus any attributes that the class specifies. Similarly, its children will be the children explicitly given in the object, plus any children that are specified in the class. The class construct() method is called, with these attributes and the parent view.

The steps happen in the following sequence:

  1. A single dictionary is created which combines the attributes of the instance with the attributes of the class

  2. A single array is created which combines the children of the instance with the children of the class

  3. construct(args, parent) is called. args is a dictionary of your attributes, parent is the lexical parent. This method can only be declared in a class, not in an instance. You can modify the arguments or the parent before calling super.construct.

  4. Any <handler name="..."> for the class or event handlers (e.g. onclick in the tag) for the class are created for the instance

  5. Attributes with when="immediately" values are applied

    1. Attributes with no setters are set

    2. Special LFC attributes are set

      • The name and id attributes

      • Event handlers and methods

      • The classroot attribute

      • Datapath children are created (datapath set using <datapath xpath="...">)

    3. Attributes with setters (<attribute name="foo" value="0" setter="setfoo(foo)" />). setfoo(0) will be called before initialization and before children are instantiated, but after you have a parent and the attributes mentioned above applied)

  6. createChildren() is called with an array of children with the superclass' children first (deepest first). There are two options for how children are created: synchronously and asynchronously. When whichever method is chosen completes, __LZinstantiationDone will be called on this instance.

    Synchronous construction

    No other code can run until all the children for this instance are created

    intstage="immediate"

    new classname(parent, args, children, false) or any trailing args are omitted, e.g. new classname(parent, args)

    Asynchronous construction

    Children for this instance will be put on the LzInstantiator queue and created later.

    initstage="early"

    initstage="normal"

    Children will be created at high priority

    initstage="late"

    Children will be created at low priority

    intstage="defer"

    Children are not created until completeInstantiation() is called

  7. After the children have been created, initialization will happen if:

    • initstage="early"

    • The instance's immediateparent has already been initialized

    • The instance is the canvas

    • The completeInstantiation() was called

    otherwise initialization will be triggered by this instance's immediateparent being initialized.

  8. Initialization

    1. Resolve references:

      1. $once{...}

        [Note] Note

        A $once constraint is an optimization: by using it you are telling the compiler not to track changes in the values the constraint depends on. If the value depends on another constraint (including CSS constraints), which does have dependencies in both applicability and value, the $once optimization is invalid.

      2. $always{...}

      3. <method..." reference="...">

    2. Initialize subviews that are not initstage="late" or initstage="defer"

    3. Call the init() method

    4. Send the oninit event