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

Binding in Flex: How to make a variable automatically update when another variable is changed?

我知道可以使组件的参数依赖于变量,前提是该变量包含 [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'}"/>

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

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

在这种情况下,您所要做的就是更新您的 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 tag and Binding to functions, Objects, and Arrays 也是很好的背景阅读资源。

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

import mx.events.PropertyChangeEvent;

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

我找到了一个解决方案,但如果有人有更清晰的解决方案,可以利用内置的 Flex 功能,请 post 它。

每次更改 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'}"/>

您还可以使用 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>

希望能帮到你。