FLEX元标签_Bindable

来源:互联网 发布:淘宝直通车和钻石展位 编辑:程序博客网 时间:2024/06/10 19:07

原文地址:http://blog.chinaunix.net/uid-122937-id-3010668.html

1 概述

       [Bindable]是元标签,元标签不是语法的一部分,而是专门给编译器用的,是告诉编译器做某些事情。
       [Bindable]的作用是:告诉 flex编译器给某些某些东西建立绑定关系

       当你在没有添加事件设置的情形下使用 Bindable 标记时,propertyChange 是将被下发的默认事件类型。 因此,[Bindable] 标记等同于 Bindable(event="propertyChange")或[Bindable("propertyChange")]。

下面的代码
  1. [Bindable]
  2. public var testData:String;

 <mx:Text x="54" y="56" text="{testData}"/>

由于没有设置事件名称,编译器将创建下列代码:
  1. [Bindable(event="propertyChange")] 
  2. public function get testData():String 
  3. { 
  4.    return this._1147269284testData; 
  5. } 

  6. public function set testData(value:String):void 
  7. { 
  8.    var oldValue:Object = this._1147269284testData;
  9.    if (oldValue !== value) { 
  10.       this._1147269284testData = value;
  11.       if (this.hasEventListener("propertyChange")) 
  12.          this.dispatchEvent(mx.events.PropertyChangeEvent.createUpdateEvent
  13.          (this, "testData", oldValue, value)); 
  14.       } 

      
Text控件监听propertyChange事件,如果有事件发生,则通过get方法修改其绑定的值

3 属性绑定

3.1 在类的属性之前
       格式为:
  1. [Bindable]
  2. public var foo;
    如果没有标出触发绑定的事件,正如[Bindable],Flex会自动为绑定加上propertyChange事件,当源数据发生变化时,Flex将自动派发该事件,触发数据绑定。如果修改后的数据和源数据“===”也就是全等,那么Flex将不会触发数据绑定。

    如果标出的触发绑定的事件,正如[Bindable(event="eventname")],那么在源数据发生改变的时候,必须dispatch出该事件才能触发数据绑定。不论修改后数据和源数据是否全等,Flex都将会触发数据绑定,需要自己编程控制,例如:

点击(此处)折叠或打开

  1. <fx:Script>
  2.             <![CDATA[
  3.                 [Bindable(event="hhhh")]
  4.                 private var ss:String="aaa";
  5.                 
  6.                 private function doTest():void
  7.                 {
  8.                     ss="bbb";
  9.                     
  10.                     if(ss!=="aaa")//判断和源数据是否相等,不相等则触发绑定
  11.                         this.dispatchEvent(new Event("hhhh"));
  12.                 }
  13.             ]]>
  14.         </fx:Script>
  15.         
  16.         <mx:Text x="54" y="56" text="{ss}"/>
  17.         <s:Button x="94" y="56" click="doTest()"/>
     在变量ss上加Bindable,是说明该变量的值如果改变会派发hhhh事件,只要是跟该变量绑定的控件,就会监听这个事件。
     如果没有this.dispatchEvent(new Event("hhhh"))这句或[Bindable(event="hhhh")],那么你点击按钮是没有设么作用的。

      这么做还有一个好处,修改了默认的监听事件propertyChange,因为propertyChange事件会比较多,这样省略了大量的判定,提高了处理速度。
      如果我们想修改Bindable的事件,一般写代码时,会写成下面的格式。

3.2 在属性的getter或setter方法之前
      这是最常见的写法
      最好同时定义getter和setter方法,给getter或setter函数加上[bindable],用不着两个都加,加一个就可以了,例如

  1. <fx:Script>
  2.         <![CDATA[
  3.             
  4.             public var ss:String="aaa";
  5.             
  6.             var i:int=1;
  7.             var j:int=1;
  8.             
  9.             [Bindable("hhhh")]
  10.             public function get gg():String
  11.             {
  12.                 lb.text="get gg被调用"+i.toString();
  13.                 i++;
  14.                 return ss;
  15.             }
  16.             public function set gg(value:String):void
  17.             {
  18.                 ss=value;
  19.                 lb2.text="set gg被调用"+j.toString();
  20.                 j++;
  21.                 
  22.             }
  23.             private function doTest():void
  24.             {
  25.                 gg=Math.random().toString();
  26.                 this.dispatchEvent(new Event("hhhh"));
  27.             }
  28.         ]]>
  29.     </fx:Script>
  30.     <s:Label id="lb" x="180" y="30" text="get"/>
  31.     <s:Label id="lb2" x="180" y="60" text="set"/>
  32.     <s:Button label="{gg}" x="80" y="30" width="50" height="50" click="doTest()"/>
      注意Button中绑定的不能是ss变量,而是gg,如果是ss,点击按钮后,Button的label值不会修改。
网页刚启动时,结果如下

说明Button中label的值,是通过get gg()函数获取的。当我们点击一下按钮,结果如下

点击了一次按钮后,
      gg=Math.random().toString();使得set gg()函数被调用了次,
      由于派发了事件hhhh,监听器监听到后,调用get gg()修改了Button中label的值,而get gg()被调用了2次,多了一次,无法解释
 

4.对象绑定
     假设有一个对象NonBindableObject,拥有二个属性
      [Bindable]
      public class NonBindableObject extends Object{
          public var stringProp:String = "String property";
          public var intProp:int = 52;
      }

      如果在申明对象时没有在类前加上[bindable]标签,那么该对象的所有属性是不能被绑定的,也就是说当对象属性发生变化时,不会触发绑定,所以点击前两个按钮都是没有用的,只有当该对象本身发生变化时,才能够触发绑定,正如第三个按钮的操作。

点击(此处)折叠或打开

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
  3.              xmlns:s="library://ns.adobe.com/flex/spark" 
  4.              xmlns:mx="library://ns.adobe.com/flex/mx"
  5.              minWidth="955" minHeight="600"
  6.              creationComplete="initObj()"
  7.              >
  8.     <fx:Declarations>
  9.         <!-- 将非可视元素(例如服务、值对象)放在此处 -->
  10.     </fx:Declarations>
  11.     <s:layout>
  12.         <s:VerticalLayout/>
  13.     </s:layout>
  14.     
  15.     <fx:Script>
  16.         <![CDATA[
  17.             import mx.events.FlexEvent;
  18.             [Bindable]
  19.             public var myObj:NonBindableObject = new NonBindableObject();
  20.             
  21.             [Bindable]
  22.             public var anotherObj:NonBindableObject =new NonBindableObject();
  23.             
  24.             public function initObj():void {
  25.                 anotherObj.stringProp = 'anotherObject';
  26.                 anotherObj.intProp = 8;
  27.             }

  28.             
  29.         ]]>
  30.     </fx:Script>
  31.     
  32.     <mx:Text id="text1" text="{myObj.stringProp}"/>
  33.     <mx:Text id="text2" text="{myObj.intProp}"/>
  34.     
  35.     <mx:Button label="改变 myObj.stringProp"
  36.              click="myObj.stringProp = 'new string';"/>
  37.     
  38.     <mx:Button label="改变 myObj.intProp"
  39.              click="myObj.intProp = 10;"/>
  40.     
  41.     <mx:Button label="Change myObj"
  42.              click="myObj = anotherObj;"/>
  43.     
  44. </s:Application>


点击(此处)折叠或打开

  1. package
  2. {
  3.     [Bindable]//去掉后属性就会没有绑定效果
  4.     public class NonBindableObject extends Object
  5.     {
  6.         public function NonBindableObject()
  7.         {
  8.             super();
  9.         }
  10.         
  11.         public var stringProp:String = "String property";
  12.         
  13.         public var intProp:int = 52;
  14.     }
  15. }


      如果对对象进行绑定,则会绑定所有的public属性和拥有getter和setter方法的属性具有绑定功能。
     
5.数组与绑定
      如果把数组作为绑定对象,那么最好使用ArrayCollection对象,因为当使用ArrayCollection对象的一些API来操作数组会触发数据绑定,如:ArrayCollection.addItem(), ArrayCollection.addItemAt(), ArrayCollection.removeItem(), and ArrayCollection.removeItemAt()方法,不然要直接使用Array的话,只用当Array本身发生变化时才触发数据绑定,当数组中某一属性发生变化时是不会触发数据绑定的。

6.绑定的使用方式
6.1mx:Binding
      数据绑定除了用[Bindable]标签来申明以外,也可以用<mx:Binding/>组件和ActionScript实现。
例如:
      <mx:binding source="text1.text" destination="text2.text"/>
      <mx:binging source="text2.text" destination="text1.text"/>
      <mx:TextInput id="text1"/>
      <mx:TextInput id="text2"/>

      source为绑定源,destination为目的源,按上面的写法,不论是text1还是text2发生变化,都会引起对方的变化。由于flex机制优化过,不会引起死循环。

6.2 bindProperty()函数
      bindProperty(site:Object, prop:String,host:Object, chain:Object,commitOnly:Boolean = false):ChangeWatcher,
例如:
      var myc:ChangeWatcher=BindingUtils.bindProperty(text2,"text",text1,"text");

      即当text1的值发生变化时text2也跟着变,site为目的对象,prop为目的属性,host为绑定源,chain为绑定源属性链——关于属性链下面再讲,commitOnly默认为False,即不管是确认事件还是未确认事件都将触发绑定,而为True时,只有确认事件才能触发绑定,这个一般用不到,和Flex自身的事件机制有关,如果为false的话,当数据改变时将触发两次绑定事件,当为True时,只触发一次,自己可以用bindSetter方法来做测试。当不想绑定时可以用myc.unwatch()方法来解除绑定。

6.3 使用bindSetter()
      bindSetter(setter:Function, host:Object, chain:Object,commitOnly:Boolean = false):ChangeWatcher

例如:
      var myc:ChangeWatcher=BindingUtils.bindSetter(change,text1,"text",true);
      private function change(str:String):void
      {
            text2.text=str;

      }
change就是当绑定源发生变化时所触发的函数,其他参数都一样。

6.4 使用ChangeWatcher.watch()
      同样可以用ChangeWatcher.watch方法来监控对象属性的变化,非常有用。
      watch(host:Object, chain:Object,handler:Function,commitOnly:Boolean = false):ChangeWatcher,

例如:
      var myc:ChangeWatcher=ChangeWatcher.watch(text1,"text",change);
      private function change(e:Event):void
      {
            text2.text=text1.text;
      }

这里的Event和绑定数据所定义的触发事件有关,你可以用所有事件的父类Event来表示。

注意:
      as主要是通过mx.binding.utils.BindingUtils 这个类来实现数据绑定,用MXML和as实现数据绑定有以下几点不同:
      1.当使用AS做数据绑定时,bindProperty()或 bindSetter()方法中不能使用AS代码,这和MXML是不同的,可以用bindSetter() 方法来申明一个绑定处理函数。
      2.当使用AS做数据绑定时,同样不能使用EX4语法,也就是说不能直接使用XML解析语法了。
      3.当使用AS做数据绑定时,在属性链中不能使用任何函数和数组。
      4.MXML具有更好的错误提示和警告功能。

最后来讲讲属性链。
      属性链就是bindProperty()和 bindSettet()等方法中的chain参数所表示的对象,有时也许绑定源并不只是text1.text这样的简单形式,也可以是类似于 user.name.text1.text,那么就存在一个关系链的问题,如果这条链中的某一项发生了改变,会不会触发绑定呢?答案是如果你想让其改变其 中的某一项都能触发数据绑定,那么这条链的每个元素必须是可绑定的。对于上面的这种形式,可以这样使用bindProperty方法:
      bindProperty(text2, "text", this, ["user", "name","text1","text"])。

参考文献
1.Flex 2 中的元数据标签. http://www.iteye.com/topic/152024 
2.如何使变量进行Flex数据绑定. http://developer.51cto.com/art/201007/215153.htm
3.Flex Data Binding详解. http://www.bianceng.cn/webkf/flex/201004/16558.htm
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 千牛聊天页面买家信息不显示怎么办 秒拍存草稿箱的视频没了怎么办? 登录山东掌厅出现服务器错误怎么办 微信号被多人投诉被限制登录怎么办 联想平板电脑开机密码忘记了怎么办 申请的qq没登录忘了账号怎么办 炫舞时代由于网络原因登不上怎么办 qq申请太多进不了热聊怎么办 手机号申请的微信号被盗了怎么办 买菜别人少找了钱不还怎么办 在掌上英雄联盟买皮肤买错区怎么办 win8我的电脑图标没了怎么办 英雄联盟老是卡在安全扫描怎么办 英雄联盟活动送皮肤没送怎么办 电脑换完系统有些页面打不开怎么办 王卡助手交手机费页面打不开怎么办 在浏览器上打不开路由器页面怎么办 英雄联盟读条的时候自动关机怎么办 手机的位置信息开不了怎么办呢 滴滴车主接到乘客返回路程要怎么办 移动换话费积分是发什么短信怎么办 手机店积分换手机被贷款怎么办 心悦俱乐部礼包已过期是怎么办 心悦兑换的东西不是账号绑定怎么办 心悦会员绑定的手机号不用了怎么办 想在京东商城开个网店怎么办呢 京东买了东西收货了不想要了怎么办 京东转卖的商品有问题怎么办 如果衣服下架了然后有退货怎么办 想买二手车可没有懂车的人怎么办 买车的时候异地车牌回家怎么办 天猫下单显示下单人数太多券怎么办 英雄联盟进入游戏后无限崩溃怎么办 打开电视显示百度影棒打不开怎么办 家里路由器网速一会快一会慢怎么办 用快看影视下载电影网速太慢怎么办 苹果手机下载东西网速特别慢怎么办 网上买重庆时时彩输了很多钱怎么办 找不到自己在哪个平台借过钱怎么办 九游账号绑定手机之前绑定的怎么办 九游充过钱的游戏忘了游戏名怎么办