Halo Navigators and Spark Containers Specification

Alex Harui (Dev)
Rob Vollmar (QA)

Functional and Design Specification


Glossary


DI - Deferred Instantation - In DeferredInstantiation, a container's children are not always created at the usual point in the component lifecycle (when addChild'd to the parent).
creationPolicy: Controls whether a DI capable container will actually defer creation of its children
IDeferredContentOwner - An interface for containers that defer creation of their children. Spark SkinnableContainer is the only implmentor of this interface right now

Summary and Background


Halo Navigators (ViewStack, TabNavigator, Accordion) are highly useful and popular controls in existing Flex applications. Unfortunately, there is no time on the schedule for a Spark-based equivalent. Currently, Spark Containers cannot be used in Halo Navigators. The compiler checks to see if Navigator children extend mx.core.Container. The navigators have APIs like selectedChild that assume the child extends Container. There has been considerable feedback from customers to allow Spark Containers to work in Halo Navigators.

Usage Scenarios


Jane wants to use the new Spark GraphicElements on every view in a TabNavigator. Unfortunately, she gets an error trying to put GraphicElements in Halo Containers and different errors trying to put the Graphic Elements in a Spark Container and putting the Spark Container in a Halo Navigator.

Detailed Description


The changes required to allow Spark Containers in Halo Navigators are:

  1. Create INavigatorContent interface extends IDeferredContentOwner
  2. Add deferredContentCreated to IDeferredContentOwner so we know that content has been created
  3. Create new spark.components.NavigatorContent extends SkinnableContainer implements INavigatorContent
    1. Override default creationPolicy to be "none" instead of "auto"
  4. mx.core.Container and NavigatorContent implement INavigatorContent
  5. Modify ViewStack and Accordion to remove dependencies on children extending Container and depend on INavigatorContent
    1. selectedChild now returns INavigatorContent
    2. call createDeferredContent instead of createComponentsFromDescriptors
  6. Modify Compiler to check that Navigator children implement INavigatorContent instead of extending mx.core.Container

API Description


package mx.core
{
/**
 *  NavigatorContent is an IDeferredContentOwner with label and icon properties
 *  that dispatch notifications when those properties change
 */
public interface INavigatorContent extends IDeferredContentOwner, IToolTipManagerClient
{
    [Bindable("labelChanged")]
	function get label():String;

    [Bindable("iconChanged")]
	function get icon():Class;
}
}

ViewStack and Accordion selectedChild properties change signature to be of type INavigatorContent

    public function get selectedChild():INavigatorContent
    public function set selectedChild(value:INavigatorContent):void

IDeferredContentOwner gets a new deferredContentCreated flag

    /**
     *  A flag that indicates whether the deferred content has been created.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    function get deferredContentCreated():Boolean;

mx.core.Container gets a createDeferredContent method that calls the old createComponentsFromDescriptor

    /**
     *  IDeferredContentOwner equivalent of createComponentsFromDescriptor(true)
     *
     *  @see createComponentsFromDescriptors
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function createDeferredContent():void

B Features


It has surprised many that Group can't and still won't be usable as a Navigator child container. The primary reason is that it isn't a DI container. If we get serious pushback from the community we can consider allowing Group in even if it doesn't handle DI, but the performance implications of effectively having creationPolicy="all" must be considered.

Examples and Usage


MXML now allowed:

    <mx:ViewStack id="vs" selectedIndex="{tb.selectedIndex}">
        <s:NavigatorContent label="bar">
            <s:layout>
                <s:VerticalLayout />
            </s:layout>
            <s:SimpleText text="bar" />
            <s:TextInput />
        </s:NavigatorContent>
    </mx:ViewStack>

ActionScript now allowed:

        var newContainer:NavigatorContent = new NavigatorContent();
        newContainer.label = tiName.text;
        newContainer.layout = new VerticalLayout();
        var st:SimpleText = new SimpleText();
        st.text = tiName.text;
        var ti:spark.components.TextInput = new spark.components.TextInput();
        newContainer.mxmlContent = [ st, ti ];

        vs.addChild(newContainer);

Additional Implementation Details


None

Prototype Work


Prototype complete

Compiler Work


Described in detailed description

Web Tier Compiler Impact


None

Flex Feature Dependencies


None

Backwards Compatibility


Syntax changes

ViewStack and Accordion selectedChild properties change signature to be of type INavigatorContent

    public function get selectedChild():INavigatorContent
    public function set selectedChild(value:INavigatorContent):void

Behavior

None

Warnings/Deprecation

None

Accessibility


None

Performance


None

Globalization


None

Localization


Compiler Features

mxml.builder.ComponentBuilder.HaloNavigatorsRequireHaloContainerChildren warning message updated

Framework Features

None

Issues and Recommendations


None

Documentation


Need examples of using NavigatorContent in a ViewStack

QA


None


You must be logged in to comment.