Flex:组件之间的绑定

时间:2012-08-30 16:03:46

标签: flex binding

以下简化示例

我有2个可视组件(PersonPicker和PersonViewer),当对象(Person)发生变化时需要对应。

即使更改了该组件中人员的值,PersonViewer的setter显然也不会被调用。我需要这个,因为当人的价值发生变化时,我需要调用另一个函数(calculateSalary)。

此函数最初被正确调用,但是当更改PersonPicker中的人员时,不再调用setter,这会导致工资标签保持初始值。

人员类

package
{
    [Bindable]
    public class Person
    {
        private var _name:String;

        public function Person()
        {
        }

        public function get name():String
        {
            return _name;
        }

        public function set name(value:String):void
        {
            _name = value;
        }

    }
}

主要应用

<?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" xmlns:local="*"
               creationComplete="creationCompleteHandler(event)">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    <fx:Script>
        <![CDATA[
            import mx.binding.utils.BindingUtils;
            import mx.events.FlexEvent;

            protected function creationCompleteHandler(event:FlexEvent):void
            {
                // Bind the person property of the personPicker to the person property of the personViewer
                BindingUtils.bindProperty(personViewer, "person", personPicker, "person");

                // Create a new Person and set this as the PersonPicker's person
                var john:Person = new Person();
                john.name = "John";
                personPicker.person = john;
            }

        ]]>
    </fx:Script>
    <local:PersonPicker id="personPicker"/>
    <local:PersonViewer id="personViewer"/>
</s:Application>

PersonPicker

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" 
         width="100%" height="100">
    <fx:Script>
        <![CDATA[
            private var _person:Person;

            [Bindable]
            public function get person():Person
            {
                return _person;
            }

            public function set person(value:Person):void
            {
                _person = value;
            }

        ]]>
    </fx:Script>
    <s:DropDownList selectedItem="@{person.name}">
        <mx:ArrayCollection>
            <fx:String>Phil</fx:String>
            <fx:String>Bill</fx:String>
            <fx:String>John</fx:String>
            <fx:String>Mike</fx:String>
        </mx:ArrayCollection>
    </s:DropDownList>
</s:Group>

PersonViewer

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100">
    <fx:Script>
        <![CDATA[
            private var _person:Person;
            [Bindable]
            public function get person():Person
            {
                return _person;
            }
            public function set person(value:Person):void
            {
                trace ("set person()");

                _person = value;

                calculateSalary();
            }

            private function calculateSalary():void
            {
                trace ("calculateSalary()");
                switch (person.name)
                {
                    case "Phil":
                        salary.text = "1000";
                        break;
                    case "Bill":
                        salary.text = "1200";
                        break;
                    case "John":
                        salary.text = "1400";
                        break;
                    case "Mike":
                        salary.text = "1600";
                }
            }
        ]]>
    </fx:Script>
    <s:layout>
        <s:HorizontalLayout/>
    </s:layout>
    <s:Label text="{person.name}"/>
    <s:Label id="salary"/>
</s:Group>

我认为这与仅更改Person对象的属性'name'有关,这不会导致调用setter。这是正确的,如果是的话,我该如何纠正我的例子呢?

1 个答案:

答案 0 :(得分:1)

PersonPicker中,您没有通过在下拉列表中选择项目来设置person属性,而是仅设置其name

解决此问题的一种方法是这样的(绑定到person属性而不是name):

<s:DropDownList selectedItem="@{person}" labelField="name">
    <mx:ArrayCollection>
        <m:Person name="Phil" />
        <m:Person name="Bill" />
        <m:Person name="John" />
        <m:Person name="Mike" />
    </mx:ArrayCollection>
</s:DropDownList>

此外,没有理由在这里使用BindingUtils。只需写下:

<local:PersonPicker id="personPicker"/>
<local:PersonViewer id="personViewer" person="{personPicker.person}" />