Flex lazy binding

Inspired by the lazy loading ability of Hibernate, I wanted to make a model part of the Flex fetch request data from the user interface only when needed. I thought it would be as simple as adding public access, which only sends server requests when accessing the variable.

public function get tab2AC():ArrayCollection
{
    if(_tab2AC == null){
        //Request data from server
    }
    return _tab2AC;
}

The problem is that Flex seems to have access to all related variables when the application starts, even if the link component has not yet been created. Therefore, even though the DataGrid dataProvider="{tab2AC}"has not yet been created, the server request is still disconnected, thereby defeating "only when needed" laziness.

I don’t want to place the server request inside the creationComplete handler, because I want my user interface model to not know the state of the view and not be aware of server requests.

Interestingly, if I add Alert.show("anything");inside the accessor, it works as I wish.

UPDATE: Here is a complete example. Set breakpoints and you will see that Flex accesses both variables, even if titleForScreen2 is not used by any component created.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
    <![CDATA[
        private var _titleForScreen1:String;
        private var _titleForScreen2:String;

        public function get titleForScreen1():String {
            if(_titleForScreen1 == null){
                //Server Request
            }                   
            return _titleForScreen1;
        }

        public function get titleForScreen2():String {
            if(_titleForScreen2 == null){
                //Server Request
            }
            return _titleForScreen2;
        }
    ]]>
</fx:Script>

<mx:ViewStack>
    <s:NavigatorContent label="Screen 1">
        <s:Label text="{titleForScreen1}"/>
    </s:NavigatorContent>
    <s:NavigatorContent label="Screen 2">
        <s:Label text="{titleForScreen2}"/>
    </s:NavigatorContent>
</mx:ViewStack>
</s:Application>
+5
source share
6 answers

, , , . Flex , , . , , , - .

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
    <![CDATA[
        import mx.binding.utils.BindingUtils;
        import mx.binding.utils.ChangeWatcher;

        private var _titleForScreen1:String;
        private var _titleForScreen2:String;

        public function get titleForScreen1():String {
            if(_titleForScreen1 == null){
                //Server Request
            }
            return _titleForScreen1;
        }

        public function get titleForScreen2():String {
            if(_titleForScreen2 == null){
                //Server Request
            }
            return _titleForScreen2;
        }

        public function updateLabel1(value:String):void {screen1Label.text = value;}
        public function updateLabel2(value:String):void {screen2Label.text = value;}

        public function bindLabel1():void {
            var changeWatcher:ChangeWatcher = BindingUtils.bindSetter(updateLabel1,this, "titleForScreen1");
        }

        public function bindLabel2():void {
            var changeWatcher:ChangeWatcher = BindingUtils.bindSetter(updateLabel2,this, "titleForScreen2");
        }
    ]]>
</fx:Script>

<mx:ViewStack>
    <s:NavigatorContent label="Screen 1">
        <s:Label id="screen1Label" creationComplete="bindLabel1()"/>
    </s:NavigatorContent>
    <s:NavigatorContent label="Screen 2">
        <s:Label id="screen2Label" creationComplete="bindLabel2()"/>
    </s:NavigatorContent>
    </s:NavigatorContent>
</mx:ViewStack>
</s:Application>
0

flex . , . , , , getter (, ) - , , , . .

, , . . , , , - .


, , . (-ish) , ( , ) .

+2
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            private var _titleForScreen1:String;
            private var _titleForScreen2:String;

            public function get titleForScreen1():String {
                if(_titleForScreen1 == null){
                    //Server Request
                }                   
                return _titleForScreen1;
            }

            public function get titleForScreen2():String {
                Alert.show("test");
                if(_titleForScreen2 == null){
                    //Server Request
                }
                return _titleForScreen2;
            }
        ]]>
    </fx:Script>

    <mx:ViewStack>
        <s:NavigatorContent label="Screen 1">
            <s:Label text="{titleForScreen1}"/>
        </s:NavigatorContent>
        <s:NavigatorContent label="Screen 2">
            <s:Label text="{titleForScreen2}"/>
        </s:NavigatorContent>
    </mx:ViewStack>
</s:WindowedApplication>

12 19, , wrapFunctionCall ( ). , 12 19, 2 - , . , . , , 2 ( , , ), , , , wrapFunctionCall . , , doPhasedInstantation, Bindings , , , , , , . , , , , .

Ah yah , , , , wrappedFuncitonCall Binding.as

catch(error:Error)
    {
        // Certain errors are normal when executing a srcFunc or destFunc,
        // so we swallow them:
        //   Error #1006: Call attempted on an object that is not a function.
        //   Error #1009: null has no properties.
        //   Error #1010: undefined has no properties.
        //   Error #1055: - has no properties.
        //   Error #1069: Property - not found on - and there is no default value
        // We allow any other errors to be thrown.
        if ((error.errorID != 1006) &&
            (error.errorID != 1009) &&
            (error.errorID != 1010) &&
            (error.errorID != 1055) &&
            (error.errorID != 1069))
        {
            throw error;
        }
        else
        {
            if (BindingManager.debugDestinationStrings[destString])
            {
                trace("Binding: destString = " + destString + ", error = " + error);
            }
        }
    }
+1

, tab2AC getter Flex , :

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;

            private var _tab2AC:ArrayCollection;

            public function set tab2AC(value:ArrayCollection):void
            {
                _tab2AC = value;
            }

            [Bindable]
            public function get tab2AC():ArrayCollection
            {
                if(_tab2AC == null){
                    trace("THIS WILL NOT BE CALLED");
                }
                return _tab2AC;
            }

        ]]>
    </fx:Script>

</s:Application>

, , , , - , , , "Step return", .

getter, .

0

ArrayCollection, null, ArrayCollection, ?

0

, , , . - , , , (, ), . , , .

, , , ?

0

All Articles