在Flex中绑定:如何在另一个变量更改时自动更新变量?

时间:2015-11-04 14:54:36

标签: actionscript-3 flash flex adobe bindable

我知道只要变量包含[Bindable]标记,就可以使组件的参数依赖于变量。这意味着更新Bindable变量的值会自动更新组件。

是否可以使另一个变量依赖于Bindable变量?

在下面的示例中,我有一个绑定的变量btnClicked。当调用函数btnClick()更改btnClicked时,TextArea中的文本将按预期更新。

我希望能够在更新btnClicked时更新另一个变量btnText。我不知道如何传达这种依赖。在下面的代码中,btnText的值最初是" clickMe"正如所料。但是,当btnClicked更改时,按钮上的文本不会更新为" unclickMe"。

<fx:Script>
    <![CDATA[
        [Bindable]
        public var btnClicked:Boolean = false;

        public function btnClick():void{
            btnClicked = !btnClicked;
        }

        [Bindable]
        public function get btnText():String{
            return btnClicked?"unclickMe":"clickMe";
        }
    ]]>
</fx:Script>

<s:Button click="btnClick()" label="{btnText}"/>

<s:TextArea y="50" text="{btnClicked?'Button is clicked':'Button is unclicked'}"/>

如何更改上面的代码,以便在更改btnClicked时btnText自动更新?

是否可以拥有一个任意长的连接变量链,每个连接变量在前一个更新时都会更新?

3 个答案:

答案 0 :(得分:3)

您还可以使用ChangeWatcher来检测可绑定属性的更新时间:

<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" creationComplete="init(event)">

    <fx:Script>
        <![CDATA[

            import mx.binding.utils.ChangeWatcher;
            import mx.events.FlexEvent;

            public var watcher:ChangeWatcher;

            [Bindable]
            public var btnClicked:Boolean = false;
            [Bindable]
            public var btnText:String = 'clickMe';

            protected function btnClick():void {
                btnClicked = !btnClicked;
            }

            protected function init(event:FlexEvent):void
            {
                watcher = ChangeWatcher.watch(this, 'btnClicked', watcherListener);
            }

            protected function watcherListener(event:Event):void {
                btnText = btnClicked ? 'unclickMe' : 'clickMe';
            }

        ]]>
    </fx:Script>

    <s:Button x="303" y="30" label="{btnText}" click="btnClick()"/> 
    <s:TextArea x="303" id="txt" y="96" text="{btnClicked ? 'Button is clicked' : 'Button is unclicked'}"/>

</s:Application>

希望可以提供帮助。

答案 1 :(得分:2)

在这种情况下,您所要做的就是更新btnClick功能以发送PropertyChangeEvent

public function btnClick():void{
    btnClicked = !btnClicked;
    dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE));
}

这是因为[Bindable]的工作原理 - 请参阅What does [Bindable] mean in actionscript?以获得一个很好的解释。 Using the Bindable metadata tagBinding to functions, Objects, and Arrays也是阅读背景的好资源。

编辑:不要忘记导入语句!

import mx.events.PropertyChangeEvent;

如果您在键入ctrl-spacePropertyChangeEvent,Flash Builder将为您插入导入语句。

答案 2 :(得分:1)

我找到了一个解决方案,但如果有人使用内置Flex功能的清洁解决方案,请发布。

以下代码每次更改btnClicked的值时都会更新btnText的值。它通过为btnClicked设置一个显式调用函数updateBtnText的setter函数来实现这一点。有关getter和setter如何允许您在读取或写入变量时调用其他函数的更多信息,请参阅this explanation

<fx:Script>
    <![CDATA[
        private var _btnClicked:Boolean = false;

        [Bindable]
        public function get btnClicked():Boolean{
            return _btnClicked;
        }

        public function set btnClicked(newBtnClicked:Boolean):void{
            _btnClicked = newBtnClicked;
            updateBtnText();
        }

        private function updateBtnText():void{
            btnText = btnClicked?"unclickMe":"clickMe";
        }

        public function btnClick():void{
            btnClicked = !btnClicked;
        }

        [Bindable]
        public var btnText:String = btnClicked?"unclickMe":"clickMe";

    ]]>
</fx:Script>

<s:Button click="btnClick()" label="{btnText}"/>

<s:TextArea y="50" text="{btnClicked?'Button is clicked':'Button is unclicked'}"/>