`
friendsys
  • 浏览: 338224 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

Flex CookBook 读书笔记 第一部分

阅读更多
定义数组和对象
可以通过ActionScript或者在Mxml中定义
<mx:Array>
<mx:String>flex</mx:String>
<mx:String>flex</mx:String>
</mx:Array>
也可以定义多维数组
<mx:Array>
<mx:Array>
<mx:String>flex</mx:String>
<mx:String>flex</mx:String>
</mx:Array>
</mx:Array>

使用mxml创建Object对象<mx:Object id="xx" first="John"/> 创建一个对象,当时不能创建嵌套对象,需要使用在Script中
var object:Object=new Object();
var otherObject:object=new Object();
objec.other=otherObject;
也可以通过大括号来创建对象
var person:Object={name:"xxx",age:xxx}等用来创建一个对象
在ActionScript中创建数组
var arr:Array=new Array("red","blue"); 是通过构造函数来创建 也可以通过中括号来创建var noConstructorArray:Array=[2,3,4,5];

重写父类的方法 需要使用override关键字 在修饰符前面
override public function set date(....)...

调用类的方法 在ActionScript中使用 new 创建一个
在MXML中 使用<位置名:类名 id="xxx"> 去创建一个对象
其中的位置名为在mx:Application中配置的xmlns:cookbook="or..类名"  其中的cookbook

使用ActionScript创建的类也可以使用<cook:COdeBehind xmlns:mx="http://www.adobe.com/2006/mxml" width="200" xmlns:cookbook=
"ore.xx.*">。。。。。。。。。</cook:CO...>
其中的其他控件也可以直接调用类内部的方法  可以用于完善类的作用域,以及之间的传递参数

自定义事件 需要继承flash.events.Event类 需要重写clone()方法,以便复制本身 覆盖的方法就是new一个自己对象
创建与事件数据相关的属性  然后在实现类中使用

请注意这个类,只有当 button 被激活时才会监听到它发出的事件。如果你删除了 button ,那
么就没有东西可以激活了, keyHandler 函数也永远不会被调用。要想在程序中捕获所有的
KeyEvents 事件而不管有没有组件被激活,请添加下面的句子:
Code View:
addedToStage="stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler)"

flex下方法参数类型的定义
可以使用参数 count:int=0 的方式 或者otherValue:Object=null 的方式进行参数的初始化
然后在方法内判断参数是否和初始化有修改,决定是否进行变更,执行不同的操作

也可以使用参数(...arguments) 来定义参数列表
然后使用 for each(var arg:Object in arguments) 来遍历参数列表

常见的类型判断,在鼠标mouseEvent中使用event.target is 控件类型...来判断类型

在mxml中实现一个接口.在顶层的组件中使用implements属性


控件的样式不同于属性,需要使用id.setStyle("样式名",值)来动态变更样式

SwfLoader用于加载swf到flash中,只要设置source属性,可能需要注意沙箱问题,也可以在source属性中属性@Embed进行嵌入

使用lablefunction可以直接访问作为dataProvider数据源中的单个记录的属性,这样就可以用于合成指定的值,便于自定义显示

Flex控件的数据源dataProvider一般使用Collection集合对象作为数据源,如ArrayCollection和XMLListCollection,确保数据的任意变化会触发控件相应的显示,在设置数据源格式的时候,可以使用预先定义的数据源的属性,来作为数据源本身Object对象的属性,也可以通过Json的key来表示.

List类型的控件列表中,通过对应事件的item属性获取单项的完整引用,使用@属性名来访问和修改

使用Alert触发事件的detail属性来决定Alert中的哪个按钮被点击

对于控件skin皮肤的设置,先要定义一个类extends PanelSkin类 然后重写对应的方法来实现自定义样式,然后指定控件中的skin属性
来进行变更

容器部分

Box类型控件,可以定义控件之间的距离,也分为了H和V两种布局,类似Css中的盒概念来控制布局,如paddingTop等。如果要更自由的控制
布局,可以在box内部再放入容器

使用不同的坐标系统跟踪鼠标位置
1:使用MouseEvent的四个属性,用于获取鼠标的位置,LocalX和LocalY属性提供抛出mouse事件相关的组件位置,而stageX和stageY提供
与Stage相关的位置.
2:使用DisplayObject的mouseX和mouseY返回相对于容易或组件的0,0坐标的位置
3:Container类定义了contentMouseX和contentMouseY位置,描述相对于整个容易内容的位置.

使用maxWidth和MaxHeight样式属性定义组件,用于防止组件超出界面显示,会使用一个新的容器进行保存超出范围的新组件.

在使用top,left等基于约束的布局设置时候,可以在值里面使用id:值来设置相对控件id位置 如 right="leftID:0"

组件的滚动条设置,通过horizontalScrollPolicy和verticalScrollPolicy属性来控制,如果要全部显示,使用on值,反之使用off,设置auto为自动显示使用horizontalScrollPosition和对应的verticalScrollPosition属性用于动态的控制滚动条,int类型操作

使用容器的creationPolicy属性来决定什么时候创建组件

flex可以直接使用组件的explicitHeight和explicitWidth属性指定组件的像素尺寸.

容器内包含组件的数量使用numChildren来访问,使用enabled来控制是否选中可用

使用UIComponent.getBounds(this.stage)可以获取组件的大小,以及x,y等属性

PopUpManager.createPopUp方法返回一个被创建对象的引用,可以用于升级成centerpop或者用于移除,可以添加到一个数组内,便于全局访问

控制组件的可见性和布局,includeInlayout属性用于表明是否保存子组件原有的空间,false为不保留 visibility设置为false用于显示与否

Graphics.beginBitmapFill(,,,)方法用于填充图片到指定区域 使用endFill()结束

Flex中正则的使用 var regexp:RegExp=/<.../  if(regexp.test(str)) 其中str为需要测试的内容是否包含正则
定义另外一种正则的方式使用regexp=new RegExp("字符串")来定义一个正则表达式

Array数组的filter方法需要一个function作为参数,用于过滤指定的字符内容,function函数带3个参数,返回Boolean

enter事件用于处理回车按钮事件

可以使用TextField来自定义一个文本控件,不过需要将TextField添加到一个UIComponent里面,可以设置完整的属性定制.
textInput = new TextField();
textInput.multiline = true ;
textInput.wordWrap = true ;
textInput.type = flash.text.TextFieldType.INPUT;
textInput.addEventListener(TextEvent. TEXT_INPUT,checkInput);
addChild(textInput);

TextRange类接受一个用于TextField的组件,用一个参数指明是否通过TextRange中的属性设置来对组件进行修改.然后用两个整数决定TextField中的起始字符和结束字符.  其中TextArea的selectionBeginIndex,以及selectionEndIndex用于显示选中的内容范围int

使用loader加载的数据 只能作为数据源赋值给组件,不能直接展示在页面之上

在TextArea中可以使用CDATA包装好的mx:HtmlText属性用于加载图片或者swf 其中使用<img>为主 他的src属性用于指定路径

如果需要调用TextField的setSelection方法 需要直接继承TextField类来实现选中效果

使用@font-face用于嵌入字体
@font-face{
src:url(".....");
fontFamily:DIN;
advancedAntiAliasing:true;
} 其中DIN为引用的字体名称

组件中的iconFunction以及Lablefunction属性用于指定一个函数,分别返回class类(图片)以及String 用于自定义图片或者文字标签

始终httpService请求数据时,使用id.lastResult获取到返回结果

在Tree控件中 要自定义渲染器,需要继承TreeItemRenderer来实现

对List组件内容进行编辑时,会触发三个事情,其中最后一个事件itemEdiEnd事件的触发函数里面包含了一个ListEvent的事件类型,其中包含了一个reason的属性判断用户是否修改了itemEdior的值
例子:event.reason=="cacelled" 来判断用户是否取消了修改
var bewData:String=TextInput(event.currentTarget.itemEditorInstance).text 来获取输入的值
event.preventDefault()来取消修改,使用默认值
其中通过TextInput(listInstance.itemEditorInstannce).setStyle("borderColor",0Xff0000)来设置样式,其中listInstance为List的ID

用于向组件添加右键菜单的例子: 主要使用ContextMenu和ContextMenuItem 以及使用push的方式
var personMenu:ContextMenu =new ContextMenu();
var lookupRecord:ContextMenuItem =new ContextMenuItem( "Look UpUpUp Record");
var lookupPicture:ContextMenuItem =new ContextMenuItem("Look UpUpUp Picture");
personMenu.customItems.push(lookupRecord);
personMenu.customItems.push(lookupPicture);
this .contextMenu = personMenu;

通过源码,可以了解到一些方法,通过继承然后重写里面的方法来实现一些特效,比如List的鼠标划过效果,可以通过override drawHighlighIndicator方法来实现修改.

DataGrid是基于列表的控件,Flex3添加了2个新控件AdvancedDataGrid和OLAPDataGrid更高级

自定义DataGrid排序,通过给DataGridColumn标签的sortCompareFunction属性赋值以执行自定义排序,
例子如下
private pfunction sortRanges(obj1:Object,obj2:Object):int{
var value1:Number = obj1.range.range1;
var value2:Number = obj2.range.range1;
ifififif (value1 < value2) {
return -1;
}
else ifififif (value1 > value2){
return 1;
}
else {
return 0;
}
}

AdvancedDataGrid提供了多列排序支持

通过给DataGrid的数据源的ArrayCollection指定一个filterfunction指定一个函数,传入一个Object对象作为参数,来实现过滤,返回Boolean值,然后使用refresh()方法来刷新数据源

AdvancedDataGrid的selectionMode属性为multipleCells和selectedCells属性为Object数组,该数组包含了被选择单元格的rowIndex和columnIndex,用于处理多选的情况,其中selectionMode属性有5种选择,此外要设置多选需要设置allowMultipleSelection属性为true

通过设置DataGrid的dragEnabled来开启拖拉 drioEnabled来开启放置,对于非列表型控件,可以使用DragManager来实现拖拽

通过设置DataGrid的editable属性为true来开启编辑功能

DataGrid中搜索并自动滚屏到匹配项,在ArrayCollection中使用IVewCursor的findFirst方法,使用DataGrid的scrollToIndex进行滚屏
例子:大概过程,新建一个sort对象 获取到数据源集合的curor对象,定义city为可排序字段,应该IViwCursor的findFirst只可以被可排序调用
private function f onResult(evt:ResultEvent): void {
ar sort:Sort = new Sort();
sort.fields = [ new SortField( "city", true) ];
this .homesForSale = evt.result.data.region;
this .homesForSale.sort = sort;
this .homesForSale.refresh();
this .cursor = this this this this .homesForSale.createCursor();
}
进行指定条件的搜索,通过.grid.scrollToIndex进行滚动到指定的行
private function searchCity(): void {
if (search_ti.text != "" ) {
if (  this .cursor.findFirst({city:search_ti.text})){
var idx:int =this .homesForSale.getItemIndex(this .cursor.current);
this .grid.scrollToIndex(idx);
this .grid.selectedItem = this.cursor.current;

GropingCollection可以用来异步更新数据源,不用全局刷新

渲染器和编辑器

创建渲染器最简单的方式,会把数据源中对应的元素赋值给itemRenderer的data属性.
<mx:list>
<mx:itemRenderer>
<mx:Component>
<mx:lable color="...."/>
</mx:Component>
</mx:itemRenderer>
</mx:list>

对于复杂类型的数据,最好重写一个Itemrenderer extends一个任意组件 如HBOX. 并且重写他的set data方法
然后在<mx:List 里面将itemRenderer属性="包名.类名"  在set data里面可以通过setStyle("","")来更新样式,也可以重写get data方法

Mxml方式的去定义个List 需要用<mx:dataProvider>..来定义数据源

Item renderer要访问父组件的一些属性,需要实现IDropInListItemRenderer,通过BaseListData类型访问renderer的父组件一些属性,其中包括使用.owner属性获取到父组件对象的引用

同时设置渲染器和编辑器,可以在dataGridColumn里面设置属性 rendererIsEditor,变更组件的状态,通过变更currentState="edit" 或者="display"进行切换

List编辑后会触发itemEditEnd事件 会带一个ListEvent类型的参数,使用event.preventDefault()来停止事件默认传播,然后再手动更新值,例子如下
list.editedItemRenderer.data= MultipleDataTypeEditor
(list.itemEditorInstance).data;
// Close the cell editor.
list.destroyItemEditor();
// Notify the list control to update its display.
list.dataProvider.notifyItemUpdate(list.editedItemRenderer); //用于直接更新数据源
}

如果要调用相对复杂的editor,比如使用NumericStepper来修改数值,需要修改DataGridColumn中的editorDataField属性为"value",表示用NumericStepper中的value属性中去取值更新.

对List增加编辑后的特效 需要在<mx:List>里面设置itemsChangeEffect属性指向,内部包含的<mx:DefaultListEffect id/> 这个只是当用户修改完成data后才触发

多媒体操作--图片,视频流等

简单的加载图片,Embed(source=".../ss.png") 然后定义个var flag:class;
当要设置成<mx:Image>数据源的时候使用 var asser:BitmapAsset=new flag() as BitmapAsset; id.source=asset;
也可以在mx:image 里面source="{flag}"

播放Mp3的方式
使用Sound和SoundChannel类,其中Sound代表一个声音文件,而SoundChannel用于控制播放
例子
var snd:Sound = new Sound( new URLRequest( "sound.mp3" ));
var channel:SoundChannel = snd.play();
也可以使用sound.load(new URLRequest("url"))来加载mp3,使用SoundTransform来控制音量
var trans:SoundTransform =new SoundTransform(volumeSlider.value,(panSlider.value - 5)/10);
chan.soundTransform = trans;

创建位图数据BitmapData的方式,先新建一个BitmapData类型,然后使用Image对象的.draw(BitmapData)进行绘制;
var maoData:BitmapData =
new BitmapData(firstImg.width,firstImg.height);
var shakeyData:BitmapData =
new BitmapData(secondImg.width,secondImg.height);
maoData.draw(firstImg);
shakeyData.draw(secondImg);

麦克风,使用Microphone.getMicrophone()去获取系统的麦克风,然后通过监听ActivityEvent.ACTIVITY判断是否有声音输入

平滑的播放视频,自定义组件包含flash.media.Video组件,然后设置视频的平滑属性为true,尤其注意需要创建单独的组件,
vid:video=new Video(width,height);
vid.soothing=true;---平滑
this.rawChildren.addChild(vid);
vid.y=50;
this.invalidateDisplayList();
然后使用vid.attachNetStream(ns) 一个newconn来加载视频,再调用ns.play("url")来进行播放

video对象的截图,并且添加数据到UrlRequest对象,并使用navigateToURL方法传送,保存JPEG图像到数据库,需要用到JPEGEncoder类的实例用于转换BitmapData对象
要点: 创建一个BitMapData对象 构造函数需要设置宽高
      使用该BitMapData对象.draw(vid) 其中vid对象为加载视频后的videoDisplay组件
      创建一个JPEGEncoder对象,构造函数使用数字100传入
      使用该对象encode.encode(BitmapData)对象 返回一个ByteArray;
      创建UrlRequest对象,设置.mothod="POST"
      创建URLVariables来附加参数 urlVars.pic=ba-----ba为byteArray对象
      设置urlRequest.data=urlVars;
      使用flash.net.navigateToURL(urlRequest, "_blank"); 直接发起请求

混合效果 设置图像的blendMode属性.

flv的附加信息onMetaData 和onCuePoint 事件作为参数被对象接受,就是需要定义个function,然后进行赋值
var obj:Object = new Object();
obj.onCuePoint = onCuePoint;
obj.onMetaData = onMetaData;
ns.client = obj;

NetStream的seek 方法从视频开头起指定秒数的点开始播放ns.seek((playhead.x/timeline.width) * length);

设置连接的常见方式
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
nc.connect(null);
然后在连接事件里面开始连接播放
private function netStatus(event:NetStatusEvent):void {
obj.onMetaData = onMetaData;
ns = new NetStream(nc);
ns.client = obj;
vid.attachNetStream(ns);
ns.play("http://localhost:3001/test.flv");
}


读取mp3文件的ID3数据 mp3文件的开头字节
sound = new Sound();
sound.addEventListener(Event.ID3, onID3InfoReceived);
sound.load(new URLRequest("../assets/1.mp3"));
onID3InfoReceived(event:Event):void{
var id3:ID3Info = event.target.id3;
for (var propName:String in id3)..
}

在加载图片的时候显示定制的动画,通过监听ProgressEvent.PROGRESS事件
image组件有两种方式显示图像,设置source和通过.load(URL).
grid.graphics.clear();用于清除旧图像
需要创建一个Matrix(); 然后m.createGradientBox(450, 40);
在加载的progress事件处理函数中,使用
grid.graphics.clear();
grid.graphics.beginGradientFill(""linear", [0x0000ff,
0xffffff], [1, 1], [0x00, 0xff], m);
grid.graphics.drawRect(0, 0, (img.bytesLoaded /
img.bytesTotal) * 300, 40);
grid.graphics.endFill();
进行填充
grid为Canvas的ID img为Image的ID

填充BitMapData的方式就是用BitMapData的实例.draw一个Image对象.
将一个BitMapData设置为Image数据的方法,通过new BitmapAsset(BitMapData)来实现,然后赋值给img.source=...
调用BitMapData.compare(BitmaoData)方法 返回两幅位图之间的差异 需要 as成 BitmapData


皮肤和样式:  flex下默认的是Halo AeonThe主题,皮肤是样式的一组属性
flex下的css是通过<mx:Style>下的.来声明的 在组件上使用styleName="..." .后的名字就可以,
如果不加.号表示此类控件都应用该样式,使用''声明字符串的样式值

使用Flex3 SDK提供的mxmlc工具将css打包,然后利用mx.styles.StyleManager在运行时加载css文件,使用loadStyleDeclarations方法
StyleManager加载的是样式swf,使用 dos下的 mxmlc MyStyles.css文件进行编译

StyleManager.loadStyleDeclarations( "assets/styles/MyStyles.swf",true); 进行加载,第二个参数用于是否加载后进行更新
使用StyleEvent.COMPLETE来监视加载完成

通过设置Canvas等组件的themeColor="haloGreen" 等来设置主题颜色,默认是haloBlue
StyleManager.registerColorName 方法来创造自定义的关键字符串值

可以使用compc工具打包swc文件 用于大范围的数据交换
> compc –include-file MyStyles.css C:/mystyles/MyStyles.css –o MyTheme.swc

嵌入自定义字体:在ActionScript中利用[Embed]元标记或者在css中使用@font-face嵌入.
[Embed(source="assets/fonts/verdana.TTF"fontName="MyVerdana" fontWeight="bold")]  然后设置fontfamily="MyVerdana"
在加入fontWeight="bold" 否则无法使用粗体

使用css的方式可以用如下格式
@font-face
{
src: url('assets/fonts/verdana.TTF');
font-family: MyVerdana;
}
可以使用unicodeRage进行字体的部分嵌入

可以使用Flash IDE中生成新的FlA文件,编译使用其携带字体
@font-face {
src: url("styles/fonts/Verdana.swf");
font-family: Verdana;
}

使用自定义的图像为组件的视觉元素应用皮肤
<mx:Button label="" upSkin="@Embed('assets/images/text_button_up.png')"/>
带skin的应该都可以使用嵌入图片,之所以使用Embed是为了放置切换的时候产生延迟
在css中使用Embed指定时,不使用前缀@,其他和桥本中嵌入一致,可以使用scale-9缩放网格信息
up-skin: Embed(source="assets/images/button_up.png",scaleGridTop="15",scaleGridBottom="20",scaleGridLeft="15",scaleGridRight="28");

可以使用Flash IDE生成的swf保存图片,然后提供加载,下面两种等效
thumbUpSkin: Embed(source="styles/scrollbar_skins.swf", symbol="thumb_upSkin");
thumbUpSkin: Embed(source="styles/scrollbar_skins.swf#thumb_upSkin");

使用编程的方法去绘制皮肤,而不是使用图像
通常来说Flex有两类组件:容器和控件,为控件生成皮肤需要继承mx.skins.ProgrammaticSkin类,为容器生成皮肤需生成ProgrammaticSkin
通常也生成Border或者RectangleBorder的子类 一共三种
需要重载受保护的updateDiplayList方法,也可以选择重载measuredWidth和Height的只读属性,默认值为0


拖拽的设置技巧,将dragEnabled绑定成一个变量{boolean} 然后在dragEnter事件被触发后进行修改,来判断是否进行拖拽

要为一个列表类自定义组件拖动图像,你需要扩展这个控件,并覆盖它的get dragImage():IUIComponent方法
通过继承IUIComponent类用于设置拖动时的显示,其中涉及到引用到list中的内容,以及代理对象ower的使用等等.
覆盖掉createChildren()方法,并且使用var list:List=List(owner);来获取父容器的引用,
然后get dragImage()中返回该IUIComponent实例,注意需要设置该实例的.owner=this;

特别:使用loader加载图片的方式: 实例化一个loader,监听Event.COMPLETE事件,添加addChild(loader)
调用.load(new URLRequest(..url))开始加载,在加载完成的事件中进行数据获取,使用
var info:LoaderInfo=LoaderInfo(evt.target);
var image:Bitmap=Bitmap(info.content);
同时可以设置image.width等进行设置

State的使用:用于控件内部状态的切换,也可以增加特效
大体结构
<mx:states>
  <mx:State name=""/>
  <mx:State name="addImg">
   <mx:SetProperty target="{this}" name="height" value="500"/>
   <mx:SetStyle target="{this}" name="backgroundColor" value="#xxxxxx"/>
   <mx:addChild relativeTo="{mainHolder}">
    <mx:Image source="../ss/ss.jpg"/>..
其中的mainHolder表示为嵌套的一个box的ID 3个类型的标签用于修改和变化,使用currentState="String" 进行状态的切换

设置State切换时候,进行effect播放,
使用Transitions对象 设置其formState和toState属性,并且将effect属性={特效ID}
和State一样,可以在transition对象定义使用setPropertyStyle或SetPropertyAction来改变样式或者当前组件的子组件属性.
targer="{id}" name="属性" value="新值"

Transition中 并行:Parallel  序列:Sequence.


State的继承
使用basedOn属性进行继承 这里注意State使用的是name来引用,不是id

使用flex框架的historyManagement机制整合states,可以用于state改变时,使用HistoryManager.saveState方法保存当前state
需要实现mx.managers.IHistoryManagerClient方法,在creationComplete="HistoryManager.register(this)" 用于注册

数据绑定使用{}或者在运行时使用bindProperty方法创建绑定
BindingUtils.bindProperty(控件ID,'属性',新控件ID,'属性');

<mx:SetEventHandler 用于在State中修改事件

State和Teansition对象都可以动态的创建,只要添加好属性,然后添加在每个UiComponent对象定义的states和transition数组中,
每个UIComponent对象都有这2个数组

使用实现IOverride接口的类,通过apply实现自定义动作,在状态切换时会自动执行,切换成其他后就会自动调用remove方法进行移除


特效Effect

可以使用ActionScript和mxml生成Effect对象,需要设置一个目标UIComponent,在ActionScript里面可以作为构造函数传入给Effect对象
在mxml里面需要使用target="{id}" 进行绑定,然后调用play()方法进行播放

自定义Effect特效, 需要创建两个类,一个继承Effect类,还有一个继承EffectInstance的实力类


集合对象常用的集合对象有ArrayCollection类和 XMLListCollection类
排序,使用coll.addItemAt({name:"James Fex",age:40},0);添加对象到数据.
使用contains和getItemIndex方法都是比较对象的指针,所以不能简单的用来比较值
如果需要进行比较和排序,可以使用Sort对象提供的findItem方法和fields方法
查找的例子:
var sort:Sort=new Sort();
return sort.findItem(coll.source,{name:"",age,Number:""},Sort.ANY_INDEX_MODE) 其中最后的参数有三种,返回的是索引

排序的方式:
var sort:Sort=new Sort();
sort.fields=[new SortField("age",false)];
coll.sort=sort;
coll.refresh();
用于asc的升序排序

ArrayCollection的数据过滤
将一个function(item:Object):Boolean函数传递给ArrayCollection的filterFunction属性,返回Boolean值判断是否保留
然后需要使用.refresh属性用于刷新,注意ArrayCollection元素并没有被过滤器函数所修改,数量等都保持不变

监听ArrayCollection数据项是否被修改
监听ArrayCollection类发出的扩展自EventDispatcher的事件类型collectionChange或者CollectionEvent.COLLECTION_CHANGE
关键在于触发的CollectionEvent类. 通用与所有的Collection集合类

分组集合GroupingCollection,使用Array作为source
创建Grouping实例,传递GroupingField对象数组给Grouping实例的fields,类似Sort的使用方法
var groupingInst:Grouping=new Grouping();
groupingInst.fields=[new GroupingField("需分组的属性")];
groupingColl.grouping=groupingInst;
groupingColl.refresh(false);
如果要传递过个分组,不能使用再建立grouping的方法,那样会覆盖掉第一次分组,需要传递多个GroupingField对象
groupingInst.fields=[new GroupingField("需分组的属性"),new GroupingField("需分组的属性")];

通过实现IHierarchicalData接口定义复杂类型的层级数据,作为DataGrid的dataProvider

遍历集合,可以使用视图游标 集合类.createCursor方法
先用Collection实例.createCursor()方法来创建游标对象,然后使用Cursor.findFirst({属性:值})来进行查找第一个对象
提供了三个主要的方法 findFirst,findlast,findAny进行查找,最后一种速度是最快的,这三个方法可以在未排序的集合中

ObjectHierarchicalData(Object)方法等使用的是将一个对象转换成Collection,而不是Array

Collection使用的过滤和排序是都使用继承的ListViewCollection类的filterFunction和sortFunction属性,或者直接传递sort类型
对象给XMLListCollection的sort属性
sort对象的关键在于fields=[new SortField("属性",false,false,true)]
记得到要使用refresh应用更新
在过滤函数中使用value.calories(@fat)访问属性,其中value为Object类型的参数

对日期类型进行比较和排序
使用mx.utils.ObjectUtil类的dateCompare方法比较日期
日期类型转换使用new Date(Date.parse("字符串")) 格式如下08/16/1982
使用sort:Sort=new Sort();
sort.compareFunction=sortFunction;
Collection.sort=sort;
Collection,refresh();
其中sortFunction(a:Object,b:Object,fields:Array=null):int  返回的结果包括 1<2=1; 1=2 =0; 1>2=-1

使用mx.utils.ObjectUtil.copy(Object)方法进行深拷贝. 该方法的工作原理是把原对象转换成ByteArray,再写到新对象上
var ba:ByteArray=new ByteArray();
ba.writeObject(objToCopy);
ba.position=0;
var objeToCopeInto:Object=ba.readObject();
通过ByteArray转换后.对象被序列化成ActionScript Message Format(AMF)二进制数据.
不过在拷贝指定类型的对象时候,需要特别的操作
需要使用flash.net.registerClassAlias方法事先在flash player中进行注册.需要两个参数完全类名和对象类型
使用var className:String=flash.utils.getQualifiedClassName(obj)获取对象的完整类名;
然后flash.utils.getDefinitionByName(ClassName) as Class获取对象类型

序列化对象的UID 类似java中的序列化ID,用于判断对象是否一致,而不用去判断属性
事先IUID接口,构造函数中使用UIDUtil.createUID();并且实现get和setuid的方法 uid:String


数据绑定
有三种方法定义数据绑定
在类中使用
[Bindable]
public class DataObject extends EventDispatcher{}...
所有可以绑定的类必须由IEventDispatcher类实现,因为数据绑定是基于事件驱动的

在变量面前只用[Bindable]
在getter/setter方法前使用[Bindable],注意放在get前
绑定的变量值更新时,会发送propertyChange事件来更新数据,也可以用[Bindable]标记接受一个事件属性
[Bindable(event="My...")];

在mxml中可以使用{}或者<mx:Binding>进行数据绑定
使用mx:Binding 可以使同一目标定义不止一个数据源
例子
<mx:Binding source="控件id.属性+'其他附加字符串'" destination="目标控件id.属性">

使用[Bindable(event="事件名")]
private Function isss():boolean{} 会在触发该事件后自动调用该方法
使用dispatchEvent(new Event("事件名")) 来触发事件
放置在set方法里面,监听值的变化

flex支持双向绑定,且不会有死循环
bindingUtils.bingProperty(目标ID,"属性",数据源ID,"属性");
通过方法BindingUtils.bindSetter,可以声明函数来处理数据绑定的源数据的更新事件,等于将数据变化指向了一个新的函数
BindingUtils.bindSetter(函数名,数据源ID,"property");
上述两个方法均返回changeWatcher对象,可以用于更新数据源,目标属性,以及停止数据绑定,其中使用unwatch来移除绑定

E4x语句;
var _data:xml=<items><item>
其中存在多个item时候,使用_data..item获取到所有的item节点.
可以使用_data..item.(@id=='1').name 用于xml的过滤,也可以调用string类型的方法

建议将多个Bindable对象合成一个代理Object对象,用于统一管理
private var obj:Object={name:'tom',geng:''};
[Bindable]
private var proxy:ObjectProxy=new ObjectProxy(obj);

验证,格式化和正则表达式
Validator验证器 Formatter 格式器
ActionScript里面的正则表达式用名为RegExp的类来表达,包含了两个主要的方法, /.../
test返回一个boolean,判断是否匹配
exec返回一个包含所有相配的项目的数组和对象

使用<mx:NumberValidator source={控件ID} property="属性" 用于绑定验证目标控件的指定属性,一般是输入控件的text
Formatter声明的方式:
<mx:PhoneFormatter id="phoneFormatter" formatString="(###)###-####" validPatternChars="#-()"/>
使用的时候id.text=phoneFormatter.format(id.text);
手工验证的时候,使用var vResult:ValidationResultEvent;
vResult=phoneValidator.validate();进行验证,然后判断属性
vResult.type==ValidationResultEvent.VALID 来判断是否验证成功
日期验证控件中,需要设置inputFormat="mm/dd/yyyy" 来设置格式
一般手动使用focusOut="function()" 来开启验证

自定义Formatter,继承Formatter类,重写format方法
使用error="错误信息" return "" 来返回错误提示
最终使用
var dataFormatter:SwitchSymbolFormatter=new SwitchSymbolFormatter();
return dataFormatter.formatValue(formatString,value);

使用数组一组的正则表达式不错的方法

自定义验证器
重写doValidation方法 返回一个Array,返回错误的时候
var err:ValidationResult=new ValidationResult(true,"","","错误提示");
reuslt.push(err) 其中result为一个Array;

验证radio button组件群是否被选中,可以判断selectedIndex属性是否为-1,可以使用NumberValidator控件
ComboBox的selectedItem为空,则未选中

批量执行验证:使用一个数组保存验证控件ID,validatorArr.push(tfValidator)
使用var ValidatorErrorArray:Array=Validator.validateAll(validatorArr)进行批量验证
然后通过判断该数组的长度,如果为0则无错误

Array.join("\n") 生成一个字符串

使用ToolTipManager去创建ToolTip,并放置在控件之上,用于显示错误,使用errorTip.setStyle("styleName","errorToolTip")
来设置提示样式
定位Tooltip, 使用var pt:Point=this.stage.getBounds(err.currentTarget.source)来定义 然后使用pt.x和.y来设置位置
完整的创建错误提示.
var errorTip:ToolTip=ToolTipManager.createToolTip(err.message,pt.x+err.currentTarget.source.width,pt.y)as ToolTip
使用TooltipManager的destoryToolTip来进行销毁
将errorTip对象保存在Array里面,便于移除

正则回顾 \d=[0-9] \D=[^0-9] \b表示一个单词 \B表示两个单词 \n表示换行符
\s表示所有空白的字符 \S表示非空白的字符 \t表示tab键 \unnnn表示对Unicode编码进行匹配
\w表示对单词字符 \W表示非单词  \xnn表示特定的ASCII编码
?表示0或1次 *表示0或者多次 +表示1次或者多次
^在外面表示开头 $表示结束单行

向前和向后匹配,去掉正则不能包含的对象或者字符
/(?<=\$)\d+/表示只截取$111后面的数字
/\b(?<!\$)\d+/表示不带$的数字
向后使用
var reg:RegExp=/pic(?!\.jpg)/表示匹配非jpg扩展名的文件 可以将!换成= 表示都.jpg文件

图表组件
Flex图表组件是Flex data visualization包中,只包含在fb专业版中
每一种图表都有一个ChartSeries对象与之对应

在series里面使用<mx:rollOverEffect><mx:fade ..><>来创建特效还有另外种为<mx:rollOutEffect>
更多的效果涉及到SeriesInterpolate,SeriesZoon,和SeriesSlide,
一般在数列对象的showDataEffect和hideDataEffect中, 其中SeriesInterpolate只能应用到showDataEffect
中,均为mx格式

让图表可选,设置selectionMode属性为single或者mulitiple, 设置成none为不可选

图表的change事件可以监听用户是否使用鼠标或者键盘改变选区,当是对程序改变选区无效

使用图表id.selectedChartItems来获取选中的数据
使用 AxisRenderer 中的样式来设置图表刻度线的外观
<mx:verticalAxisRenderers>
<mx:AxisRenderer axis=" { vertAxis } " styleName=" customTicks " />
</mx:verticalAxisRenderers>
vertAxis为坐标轴的ID

使用样式和标签函数,可以用于自定义图表的标签
图表中包括两种标签,坐标轴标签和数据标签,可以使用标签函数进行自定义配置

标签函数对于数字坐标轴,分类坐标轴和数列的用法略有不同
<mx:verticalAxis>
<mx:LinearAxis labelFunction=" { currencyAxisLabel } " />
</mx:verticalAxis>

ChartItemEvent的hitData,item.food属性来获取这个被点击的数据 其中food为数据源中的属性

要为图表更换皮肤,需要创建可以继承ProgrammaticSkin类以及实现IdataRenderer类

将一张图片设定为图表数列的 itemRenderer ,只需简单地把已嵌入的图片设置为itemRenderer 的属性即可。
<mx:PlotSeries xField="goals" yField="games" displayName="Goals per game" itemRenderer=
"@Embed(source='../assets/soccerball.png")" radius="20" legendMarkerRenderer="
@Embed(source='../assets/soccerball.png')"/>
也可以用继承类来实现..参考前面其他内容

使用ActionScript可以动态添加和删除图表中的列
使用图表id.series=[ColumnSet对象]
其中使用ColumnSet对象.series.push(Colunerises的实例)

覆盖图表组件的dragEnterHandler()和dragDropHandler()方法可创建一个可拖拽的图表

共享对象

SharedObject数据可以保存在用户的本地硬盘上,类似浏览器的cookie,使用AMF来序列化保存100k
SharedObject只能被创建他的应用程序访问,以及域问题.
本地共享对象Local SharedObjects
远程共享对象Remote SharedObject;使用FMS来保存

创建或者打开一个本地共享对象,可以使用
var myLoaclSharedObject:SharedObjec=SharedObject.getLocal("mylso");
远程共享对象可以使用sharedObject.getRemote("myRso")
文件的扩展名为.sol
var soInstance:SharedObjec=SharedObjec.getLocal("myLso");
使用soInstance.data.key="..."
所有的对象都需要附加在date.自定义key之上 否则会抛出异常
使用SharedObject.flush(大小) 来保存到硬盘上去
使用SharedObject的clear()方法删除文件,delete lso.data.key 用于删除该值

如果要保存自定义数据类型的对象到SharedObject,需要使用registerClassAlias()方法来注册flash运行时
所有共享对象都包含了一个叫做ObjectEncoding的属性,标示该共享对象使用的AMF版本.默认是AMF3 即as3格式,
如果要向后兼容,可以设置为AMF0
registerClassAlias("oreilly.cookbook.Automobile" , Automobile );
使用ObjectUtil.toString(lso.data.automobile);进行读取

使用多个应用程序中访问同一个共享对象
lso = SharedObject.getLocal("myLso", "/" ); 第二个参数用于指定路径

数据服务和服务端通信
Flex 提供了三个类来与服务器通讯: HTTPService , RemoteObject 以及 WebService 。
使用Httpservice后,数据会从服务返回,并放置在服务组件所包含的lastResult对象,默认的resultFormat为ActionScript对象

使用HTTPService组件,设置他的url为接受数据的URL,如果反馈的是XML,就需要定制处理,指定一个方法到组件的xmlDecode属性
来处理xml

<mx:HTTPService>
<mx:request xmlns="" >
<id> {requestedId} </id>
</mx:request>
</mx:HTTPService>
这次发送 中 requestedId 属性会被包装在 id 标签,然后发送到 HTTPService 对象设定的 U RL上。
要访问请求回的数据,直接使用httpservice的lastResult就可以了,不需要用事件取得结果,事件只用来判断状态

xml返回结果的处理
<mx:HTTPService url=" http://localhost/service.php " id=" service "
result="serviceResult(event)" fault="serviceFault(event)"
method=" GET " contentType=" application/xml " useProxy=" false " >
然后就可以使用service.lastResult.age 进行访问

所谓 REST ful 的服务一般被用来描述一个服务使用所有 4 个可能的 HTTP 头 : PUT,POST ,
DELETE 以及 GET 。这四个头通常对应四种基础的数据访问操作:创建,读取,更新以及删除
使用Httpservice可以直接设置id.method="Delete"类似get和post 也可以直接使用id.send("id=2")进行带参数的发送

<mx:RemoteObject id=" local_service " concurrency=" single "
destination=" http://localhost:8400/app " showBusyCursor=" true "
source=" LocalService.Namespace.Service.ServiceName " >
<mx:method name=" getNames " fault="getNamesFault(event)" result="getNamesResult(event)" />
<mx:method name=" getAges " fault="getAgesFault(event)" result="getAgesResult(event)" />
</mx:RemoteObject>

result事件返回的是ResultEvent类型的事件 使用
var namesColl:ArrayCollection = event.result as ArrayCollection; 处理返回结果的类型转换
fault事件返回的是FaultEvent类型的event.message as String来处理错误信息

var responder:Responder = new Responder( getNamesResult,getNamesFault );
var call:AsyncToken = ( local_service as AbstractService).getNames();
call.addResponder(responder);
用于给RemotObject定制事件 其中getNamesResult,getNamesFault 为函数名

加载 service-config.xml 文件需要改变 flex 的编译参数:
1, 菜单 Project->Properties
2, 选择 Flex Complier 块在 " locale en_US " 后面添加 -services service-config.xml 。
3, 确定。

[RemoteClass(alias= "project.Employee" )] 与服务器绑定对象

使用 IExternalizable  接口自定义序列化
使用 ActionScript 3 API flash.utils.IExternalizable ,它兼容 java.io.IExternalizable API.
使用类扩展该接口,并且写上两个对应的方法
public function freadExternal(input:IDataInput):  void
{
_id = input.readObject() as String;
name = input.readObject() as String;
description = input.readObject() as String;
price = input.readInt();
}

使用HttpService请求 id.send方法返回的是一个AsyncToken类型的对象
var token:AsyncToken = service.send();
可以用如下进行事件捆绑,以及设置自定义的属性month等其他任意属性
token.resultHandler = onResult;
token.faultHandler = onFault;
token.month = monthName;
在返回结果的函数里面 可以使用ResultEvent.token.属性名 进行定义属性的访问

在服务端数据改变后主动通知客户端
使用 mx.messaging.Producer 和 mx.messaging.Consumer 标签配置用于通信的目标通道和消息
事件设置事件处理器。配置这些需要使用 Adobe LiveCycle 或 BlazeDS 服务器。

Flex的消息可以是ActionScript消息和Java Message Service(JMS)消息
使用Consumer通过mx.messageing.events.MessageEvent接受消息,使用Producer使用send方法发送消息,该方法接受
mx.messaging.AsyncMessage作为参数,AsyncMessage的主体作为值发送给通道的所有订阅者
例子
<mx:Producer id=" producer " destination=" http://localhost:8400/chatDestination " />
<mx:Consumer id=" subscriber " destination=" http://localhost:8400/chatDestination "
message="receiveChatMessage(event)" />

private function sendChatMessage():  void
{
var  msg:AsyncMessage = new  AsyncMessage();
msg.body = "test message";
producer.send(msg);
}
private function receiveChatMessage(msgEvent:MessageEvent):  void
{
var msg:AsyncMessage = AsyncMessage(msgEvent.message);
trace ("msg.body" +msg.body);
}

注册服务端数据类型,就是将Javabean类和本地的ActionScript进行自动的转换
反序列化AMFshujuzhong的对象为类对象事,该类需要现在Flash Player中注册,这样反序列化才可以正常
使用e.result as 类型,获取到ResultEvent返回的类型对象.
flash.net.registerClassAlias( "oreilly.cookbook.vo.RecipeVO" ,RecipeVO);
需要先进行类注册,然后匹配的对象可以被转换成指定的类型

连接WebService
创建 mx.rpc.WebService 对象,设置 wsdl 属性为 WebService 的 WSDL 地址
<mx:WebService id="userRequest" wsdl="http://localhost:8400/service/service?wsdl">
<mx:operation name="getRecipes" result="getRecipeHandler()"
fault="mx.controls.Alert.show(event.fault.faultString)"/>
</mx:WebService>
其中<mx:operation> 用于返回结果处理函数
注意使用webservice时,需要判断当前的webservice是否可用,主要是是否载入和解析wsdl属性所指定的WSDL文件,并准备好所有的
方法已经可以调用. 可以通过WebService发出LoadEvent事件或者判断WebService组件的ready的boolean属性

<mx:WebService id=" userRequest " wsdl=" http://localhost:8500/service/service?wsdl "
load="callService()" >
<mx:operation name=" getRecipes " resultFormat=" object " fault="createRecipeFault(event)"
result="createRecipeHandler(event)" />
</mx:WebService>

添加SOAP头到WebService请求
创建一个 SOAPHeader 对象,参数为所使用的名称空间和添加到 header 的内容。然后调用WebService.addHeader 方法发送带有请求的 header

var qname:QName=new QName( ""http://soapinterop.org/xsd" , "CookbookHeaders" );
var headerone:SOAPHeader =new SOAPHeader(qname, {string: "header_one" ,int: "1" });
var headertwo:SOAPHeader =new SOAPHeader(qname, {string: "header_two" ,int: "2" });
然后再调用service.addHeader(headerone); 添加头部到服务中
添加 SOAPHeader 到指定的方法上:service.getRecipes.addHeader(headertwo);
如果SOAP不再需要了,调用WebService或者方法本身的clearHeaders方法
service.clearHeaders();
service.getRecipes.clearHeaders();

解析WebService的返回的SOAP响应,解析返回的SOAP编码的XML

使用SecureAMFChannel进行AMF的安全通信
使用AMF数据和安全的Sockets层(SSL)通过Flash Remoting进行通信,在编译程序所使用的services-config.xml中定义channel为
SecureAMFChannel
要创建一新的 channel ,使用安全版本的 AMF 类,只要在 services-config.xml 文件的 channel 中使用 mx.messaging.channels.SecureAMFChannel 作为其类,(endpoint) 终 端设置为 flex.messaging.endpoints.SecureAMFEndpoint 类:
然后在频道内,需要设置一个ChannelSet对象用于设置给RemoteObject,ChannelSet对象内也要设置好对应的SecureAMFChannel

使用Socket收发数据
要创建一个 Socket ,先要使用构造器创建 Socket 实例,调用 connect 方法,传递 IP 地址或域名和端口号作为方法参数:
Socket 可接收和发送 POP3 , SMTP , IMAP 信息
默认构造函数是空的 new Socket();
socket = new Socket();
socket.addEventListener(ProgressEvent.SOCKET_DATA,readSocketData);
socket.connect( "127.0.0.1", 8080);
socket.writeMultiByte(string,  "iso-8859-1" ); 用于写入数据,其中string是值,后面为编码
读取的时候,使用
var ba:ByteArray = new ByteArray();
trace (socket.readBytes(bs));
用于读取数据

要连接端口号低于1024的Socket,需要在站点根目录下创建一个cross-domain.xml文件,其中定义允许的端口号,
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" to-ports="80" />
</cross-domain-policy>

XMLSocket 类实现了客户端 socket ,让 Flash Player 和 AIR 应用程序可以指定 IP 地址和域
名即可连接到服务器。要使用 XMLSocket 类,服务器端必须运行一个能了解 XMLSocket所使用协议的伺服器.
XML 信息是通过全双工传输控制协议 / 互联网协议 (TCP/IP) 流发送。
var xmlsock:XMLSocket =  new XMLSocket();
xmlsock.connect( "127.0.0.1", 8080);
端口号是必须的,因为 XMLSocket 连接的端口号不能小于 1024 。给 DataEvent.DATA 事件添加监听器,用于接收数据:

xmlsock.addEventListener(DataEvent.DATA, onData);
private function onData(event:DataEvent): void
{
trace ("[" + event.type + "] "  + XML(event.data));
}
返回的字符串可转换为 XML ,使用 E4X 进行解析。

XML 可拓展标记性语言 flex主要包括了XML和XMLList
XML 对象代表单一的 XML 元素 , 一个 XML 文档或该文档中的一个单
值元素。 XMLList 则代表一组跟其他组同级的 XML 元素。 XMLList 对象不需要设置顶级节点 , 例如 :
<item id="2" name="Chewing Gum"/>
<item id="3" name="Cotton Candy"/>
<item id="4" name="Candy Bar"/>
XML 对象需要设定顶级节点 :
<order>
<item id="2" name="Chewing Gum"/>
<item id="3" name="Cotton Candy"/>
<item id="4" name="Candy Bar"/>
</order>

加载XML的方式
使用 HTTPService 组件来加载 XML 文件 , 并把 resultFormat 设置为 ” xml ” 。 或者 , 使用
flash.net.URLLoader 类来创建一个 URLLoader 实例 , 并调用 load 方法来加载 XML 文件。

在默认的情况下 , HTTPService 组件会把任何加载的 XML 转换成一个 ActionScript 对象。 要
避免这种情况 , 可以对 HTTPService 对象的 resultFormat 属性进行以下设置 :
<mx:HTTPService url=" http://server/xmlDoc.xml " i d=" xmlService "
resultFormat=" e4x "result="xmlObj=XML(xmlService.lastResult" />
httpservice的lastResult用来保存请求的结果

Event.COMPLETE 事件监听器必须添加到 URLLoader 里 , 这样当文件加载完成时 , 应用程序
就会得到通知。 所加载的数据将会存放到 URLLoader.data 属性里 , 不能被修改。

通过E4x语法遍历xml文档

使用 E4X 语法的 ” @ ” 运算符来存取属性 , “ ([]) 运算符 ( 数组索引 ) ” 是用来指示 多个子节点 之间
的关系 , 而 ” . ” 运算符则用来表示已命名 子节点 之间的关系。

xml.bar[2].@type  表示xml对象第三个bar节点的type属性
要对属性值或节点进行测试的话 , 可以使用相等运算符 (==):
trace (xmlItems.item.(@id == "2").menuName);

使用正则表达式在 E4X中进行查询
xmlItems.item.(/\d\d\d/.test(@id)).price  进行验证
任何含有 3 位数字 id 属性的项目 , 将会返回一个该属性的价格值,关键在于()内返回的boolean值
使用 E4X 表达式 , 找出需要追加的 XMLList 对象所在的节点 , 然后在该节点上调用appendChild 方法。
这里所谓的xmlList对象就是不带根节点的xml,或者直接使用xml就可以了
var newXML:XML = <item id="4"/>
xmlNode.appendChild(newXML); 其中的xmlNode为原有的XML对象

要定义XmlList对象需要使用构造函数来创建xml数据源
new XMLList('<xx>dd</xx><xx>aa</xx>');
取出指定的节点使用var node:XMLList=xmlNode.item.(@id==3);

从数组生成xml对象的方法
var arr:Array = [1, 2, 3, 4, 5];
var xml:XML =  new XML(<data></data>);
for (var i:int = 0; i<arr.length; i++) {
xml.appendChild(<id>{arr[i]}</id>);
}
要点就是通过循环访问数组下标来引用对象,使用xml.appendChild(xml)来新增到xml上

处理包含了命名控件的xml数据
private namespace w3c = "http://www.w3.org/2001/12/soap-envelope";
use namespace w3c;
通过 ” . ” 运算符可以存取任何使用限定命名空间的 XML 的 子节点 , 同时该命名空间 申明 时应
跟随着 ” :: ” 运算符及节点名义。 例如以下的 XML 对象 :
<m:PriceResult>
<m:Price>34.5</m:Price>
</m:PriceResult>
“ price ” 节点会通过以下的方法来存取 :
m::PriceResult.m::Price
要保持标签的完整性

将一个对象变成xml的方式, 这里用的是简单的Object对象
可以使用 SimpleXMLEncoder.encodeValue 方法把一 个对 象及 其属 性写 入到 一个XMLDocument 对象里。
encodeValue(obj:Object, qname:QName, parentNode:XMLNode):XMLNode
所生成的 XML 会由该方法返回 , 同时会附加到 parentNode 所在的 XMLDocument 对象内的
XMLNode 中 , 该方法会要求所有旧式 XMLDocument 所生成的 XML 附加到其中。
XMLDocument 生成以后 , 可以通过 XML 对象的构造函数 , 并将该文档当作参数传递到构造
函数中 , 由此转换成 XML 对象 :
var doc:XMLDocument =new XMLDocument( '<data></data>');
var xml:XML =  new XML(doc);

private var o:Object = {name: "Josh"  ,description_items:{height: '183cm'  , weight: '77k'  }};
doc = new XMLDocument( '<data></data>');
var simpleEncode:SimpleXMLEncoder =new SimpleXMLEncoder(doc);
var node:XMLNode = simpleEncode.encodeValue(o,new QName( 'http://localhost/ns/ws' , 'ls' ),doc.firstChild);

使用复杂的xml数据来填充组件
可以使用Tree和AdvancedDataGrid控件来显示数据,需要创建一个HierarchicalData对象,并将该xml传递给它,确保正确的定位数据

<mx:AdvancedDataGrid
dataProvider=" { new HierarchicalData(foodXML) } " width=" 100% " height=" 100% " >

将XML转换成自定义类型
通过使用限定命名空间及 SimpleXMLDecoder 类把 XML 译码成对象 , 然后使用
chemaTypeRegistry.registerClass 方法对类进行注册。

var qname:QName = new QName( "http://localhost/ns/ws","Plant"  );
mx.rpc.xml.SchemaTypeRegistry.getInstance().registerClass(qname,Plant);

SchemaTypeRegistry.registerClass 可以让你注册一个类型为由 Web 服务所返回的类。这个类一定要在 WSDL 文件被描述

与浏览器通信

连接到外部 URL
使用 navigateToURL 方法将浏览器切换到新 URL 。
navigateToURL 方法让你可以在原窗口、新建窗口或者指定的窗口框架里切换到一个新URL 。这是 Flex 应用和浏览器通信中最 普遍 的一种 方式 。要在你的 Flex3 应用里调用navigateToURL 函数,使用下面的方法:
navigateToURL( new URLRequest( newUrl.text ),target.selectedItem as String );
第二个参数为_blank等 指定打开连接的方式

使用FlashVars
从容器HTML页面传递参数给Flex
<object>和 <embed> 标签来实现,也可以用Javascript进行加载使用
<object>内<param name="FlashVars" value="param1=one&param2=2&param3=3&param4=four" />进行传递,也要在
<embed>或JavaScript内FlashVars="param1=one&param2=2&param3=3&param4=four"

在 Flex 应用程序里,你可以随时使用 Application.application.parameters 对象来访问 FlashVars数据。
var parameters : Object = Application.application.parameters;
var param1 : String = parameters.param1;
默认的是字符串类型

Flex里面调用JavaScript的函数方法
在 AS 中使用 ExternalInterface 类调用 JavaScript 函数。
ExternalInterface.call( "simpleJSFunction" );
可以在调用 JavaScript 函数的同时传入参数:
ExternalInterface.call( "simpleJSFunctionWithParameters", "myParameter" );
可以用来获取返回值
var result:String = ExternalInterface.call( "simpleJSFunctionWithReturn" );

在JavaScript中调用ActionScript方法函数
使用 ExternalInterface 在 JavaScript 里设置对 Flex 的回调方法并且在 JavaScript 里调用ActionScript 方法。

在 JavaScript 调用 ActionScript 方法之前,你需要为开放给 JavaScript 调用 的 ActionScript 方
法注册一个回调函数。回调函数通过 ActionScript 的 ExternalInterface 类来注册。回调函数 为
JavaScript 方法提供一个对 ActionScript 方法的映射。
该例示范如何为ActionScript 方法函数注册回调方法。
private function registerCallbacks() : void
{
ExternalInterface.addCallback( "function1" , callback1 );
}
其中callback1为ActionScript内的函数,返回类型和参数随意

JavaScript中的调用方法
var swf="myswf"
var container=window//火狐下写法
var container=document//IE下写法
container[swf].function1(); 则调用第一个函数,可以直接在()内带参数传递
var result=container[swf].function1(); 用于接受返回值

使用BorwerManager类的实例与HTML的DOM进行交互
var bm : IBrowserManager = BrowserManager.getInstance();
bm.init();
bm.setTitle(newTitle) 用于修改浏览器的标题,不知道还有什么其他的方法,只能使用在URL和title之上

BrowserManager 和 URLUtil 类读取并解析当前页 URL
URL 会段为两个部分:基部 (base) 和片段 ( fragment ) 。 URL 基部 (base) 包含了 # 号左边
的所有内容。片段 (fragment) 则包含了 # 号右边所有的内容。片段 (fragment) 用以传递参数给
Flex 应 用 程 序 或 者 用 于 历 史 管 理 器,URL 片段 (fragment) 的每个键 - 值对都应该用分号 (;) 分隔开

http://localhost:8501/flex3cookbook/main.html#name=Andrew;index=12345;productId=987
var o:Object = URLUtil.stringToObject(bm.fragment); 进行解析
就可以使用o.name等方式进行访问
使用BrowerManager的实例进行更新URL
bm.setFragment( "firstName=" + firstName.text ";lastName=" + lastName.text );

在 Flex 中通过实现 mx.managers.IHistoryManagerClient 接口来实现自定义的历史记录管理器。
为了实现此解决办法,历史记录管理器必须对你的 Flex 项目 / 工程是激活的。为了验证, 我
们进入 Flex Project Properties 对话框,选择 Flex Compiler 项,并验证 Enable Integration wit h
Browser 复选框处于选中状态,这即表示你的历史记录管理器对你的 Flex 项目 / 工程是激活的。
可以使用浏览器的前进后退在这个TextInput控件的所有输入之间的来回切换,JavaScript应该也可以
"mx.managers.HistoryManager.register(this );" 用于注册控件开启功能


开发策略

配合Flash IDE使用
在 Flash CS3 IDE 中安装 Flex 组件工具包( Flex Component Kit )。然后创建一个元件,并使用
[ 转换成 Flex 组件 ] 命令把它转换成组件。最后把影片发布成 SWC ,添加到 Flex 项目中就可以了。
所有的 Flex 程序默认以每秒 24 帧的速度运行,发布后,生成的是一个swc,添加在flex应用程序库就可以
<local:Cloud height=" 200 " width=" 400 " /> 加入到程序中

如果需要扩展该组件,需要在Flash IDE里面扩展UIMovieClip创建一个类,保存成FLA,然后打开库中的这个影片剪辑的链接属性,
点击输入框后的验证标示,需要把类和FlA文件放在一起,提示找到后,设置好基类flash.display.MovieClip 。
可以在Flash IDE里面写上需要的函数,可以直接在组件里面进行调用

使用 Flex 组件工具包的 [ 元件转换成 Flex 容器 ] 的命令,或者更简单的,可以在 Flash IDE 中创
建一个扩展自 ContainerMovieClip 的类,然后在你的应用程序中导入一个包含那个类的 SWC 。
ContainerMovieClip 的实例可以拥有子项;响应点击,鼠标移动,及其他事件;定义视图状
态和过渡效果;像其他 Flex 组件一样使用各种效果。尽管在编译期或运行期只能往这样的 容器中添加 一个 子项,但是你可以添加一个 Flex 容器,这样就可以添加多个项了。

把元件转换成 MovieClipContainer 实例 后,接下来就可以放置这个 FlexContentHolder 了。它 决
定了 Flex 内容可以被添加到这个容器的哪个区域,它是 mx.flash.FlexContentHolder 类的实例 。
当向它里面添加内容时,内容显示在它指定的区域中。注意, FlexContentHolder 中只能添 加
一个子项,因此任何添加进来的子项都会自动填充它的整个区域。使用 Flash IDE ,你可以
调整 FlexContentHolder 的尺寸和位置.
要想添加多个组件,可以先添加一个容器,然后进行添加

使用Flash IDE中的控件
要在 Flash CS3 中生成 SWC 文件,首先你必须创建一个新的 Flash CS3 ActionScript3 的 FLA 文
件。把想要使用的组件拖到库里,选择文件 → 导出 → 导出影片,为 SWF 文件设置一个名称 ,
并选择要保存的文件夹。在导出 FlashPlayer 对话框里,勾选 [ 导出 SWC] ,然后点确定以确 保
设置生效。
当编译这个 FLA 文件时,会生成 2 个文件:一个 SWF 文件和一个 SWC 文件。这个 SWC 文件 很
有用,你可以把它添加到 Flex Builder 的应用程序的库路径中或者使用 mxmlc 时添加到编译 选
项 libary-path 中。


优化的技巧
1:多使用as 少用try..catch
2:稀疏数组访问起来比较慢,所以把空的项填上 null 会提高速度。
3:整数运算时候,会把整数转换成数字,加完再转换回来,因此当执行数学计算时,应该尽量使用数字,最后再转换成整数Number int
4:局部变量访问速度比较快
5:组件应该尽量使用延迟的实例化
6:数据绑定会消耗内存并减慢程序的启动时间
7:不用使用容器类作为List或DataGrid的itemRenderer,应该使用UIComponent
8:记得removeEventListener,便于垃圾回收
9:对色彩丰富的UIComponent或者包含位图数据的对象使用cacheASBitmap,不过缓存的位图数据缩放的时候可能会失真.
10:在DisplayObject对象添加到现实列表前调用setStyle的开支会小一些


模块(Modules)和运行时共享库(RSLs)

创建一个可以被下载和缓存的RSLs
使用自定义类,组件和其他资源创建一个库,编译为 SWC 文件,然后解压出 SWF 文件中的
library.swf 文件,引入到你的应用程序部署目录,作为一个 RSL 使用。

这是个简单的组件,允许用户输入信息和发出一个 submit 事件。要打包这个类为 SWC 文件。
你需要调用 compc 工具,设置 source-path 和 include-classes 参数,如下面的命令生成一个
CustomLibrary.swc :
compc – source-path . –include-classes com.oreilly.flexcookbook.CustomEntryForm -output
CustomLibrary.swc
多个文件使用空格隔开

当编译应用程序时 SWC 文件作为动态链接,你可以根据需要重命名解压出来的 library 文件。在这个例子中,被命名为 CustomLibrary.swf 。

xmlns:flexcookbook=" com.oreilly.flexcookbook.* "
使用来自 RSL 中的类引用和 MXML 组件资源就像引用静态链接库和本地开发目录中的类文
件一样。在这个例子中在 <mx:Application> 标签中申明了 flexcookbook 名称空间,被用来添 加
CustomEntryForm 组件到显示列表中。
要编译使用了 RSL 的应用程序,调用 mxmlc 工具时要使用 external-library 和 runtime-shared
libraries 参数:
Code View:
> mxmlc – external-library=CustomLibrary.swc – runtime-shared-libraries=CustomLibrary.swf
RSLExample.mxml

使用跨域的 RSL,以便在不同域的应用程序都能访问到。
Compc 工具创建 RSL 时加上 compute-digest 参数后, RSL 摘要信息会在编译时期链接到 RSL 时
存储到应用程序中。然后创建跨域的授权文件引入 mxmlc 工具的 runtime-shared-library-paths
选项指定的 RSLs 位置。

下面的命令生成一个 SWC 文件命名为 CustomLibrary.swc :
Code View:
> compc – source-path . – include-classes com.oreilly.flexcookbook.CustomEntryForm -output
CustomLibrary.swc – compute-digest=true
compute-digest 选项的默认值为 true ,当编译库时你不必引入它来创建摘要。当通过 MXML 编
译器的 runtime-shared-library-paths 选项链接跨域 RSLs 时才需要摘要。

跨域授权文件是一个 XML 文件,列举出可访问数据的已授权远程服务器。 要让其他应用程序 能
找到其他域中的 RSL ,在 crossdomain.xml 文件中用 <allow-access-from> 元素列举出域:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*.mydomain.com" />
<allow-access-from domain="*.myotherdomain.com" />
</cross-domain-policy>

上面的跨域授权文件允许任何来自 http://mydomain.com 和 http://myotherdomain.com 的
SWF 访问服务器数据,包括跨域 RSLs 。

要编译动态链接到上面生成的 CustomLibrary.swf 跨域 RSL 的应用程序,调用 mxmlc 工具, 使
用 runtime-shared-library-path 参数和目标服务器上的 RSL 完整 URL 路径和跨域授权文件:
> mxmlc RSLExample.mxml – runtime-shared-library-path=
CustomLibrary.swc,
http://www.mytargetdomain.com/libraries/CustomLibrary.swf,
http://www.mytargetdomain.com/libraries/crossdomain.xml

优化RSL
使用 optimizer 命令行工具删除 SWC 文件中的调试代码和不必要的元数据。

我们创建一个 MXML 组件,保存为 MyCustomComponent.mxml :
使用下面的命令生成 SWC 文件并命名为 library.swc :
Code View:
> compc – source-path . – include-classes MyCustomComponent -output library.swc

解压出 SWC 中的 library.swf 文件,这时的大小接近 320KB 。
使用 optimizer 工具通过删除没用的调试和元数据代码减小 RSL 的大小:
> optimizer – keep-as3-metadata=
"Bindable,Managed,ChangeEvent,NonCommittingChangeEvent,Transient"
– input library.swf – output optimized.swf
优化后的 RSL 只有原来一半还少,接近 135KB.

强烈建议你保留 Bindable, Managed, ChangeEvent, NonCommittingChangeEvent, 和 Transient
元数据名称标签,其他元数据如 RemoteClass, 可以添加到 RSL 库的类依赖项所基于的逗号分隔参数列表。

创建基于MXML的模块
使用<mx:module>表示一个模块

使用 mxmlc 工具编译这个例子:
> mxmlc ContactList.mxml

创建基于 ActionScript ActionScript ActionScript 的模块
创建一个继承自 mx.modules.Module 或 mx.modules.Modulebase 的 ActionScript 类,使用 mxmlc编译模块。
通过继承 Module 和 ModuleBase 类创建基于 ActionScript 的模块。
ModuleBase 类继承自 EventDispatcher ,可被用来分离应用程序逻辑代码使之不依赖于可视化元素。
Module 类是一个显示容器,可以放置视觉对象
编译方式和基于 MXML 的模块一样,同样是使用 mxmlc 工具:
> mxmlc ASContactList.as

使用 ModuleLoader ModuleLoader ModuleLoader 载入模块
ModuleLoader 和 SWFLoader 不同之处在于它 有一个 约 定 ,这个被载入的SWF须实现 IFlexModuleFactory 。被编译的模块包 含
IFlexModuleFactory 类工厂,它允许应用程序在运行期间动态载入模块化 SWF 而不需要在主应用程序中实现此接口。
虽然 ModuleLoader 对象是一个可视的容器, 可载入继承自 Module 和 ModuleBase 的模块,不
依赖于这个模块是否包含有框架代码或可视对象。 ModuleLoader 的 url 属性指向一个模块的 具
体位置。设置 url 属性后,组件内部会调用 loadModule 方法,开始下载模块。
ModuleLoader 组件也允许你动态卸载和加载模块。对 ModuleLoader 的 url 属性的设置在内部 会
调用 loadModule 方法,添加这个模块作为子节点。调用 unloadModule 方法可删除显示列表 中
的模块。调用 unloadModule 是设置 module 引用为 null ,但是并不会改变 url 属性值。

使用 ModuleManager 载入模块
ModuleManager 类 管 理 着 加 载 的 模 块 。 当 调 用 ModuleLoader.loadModule 和
ModuleLoader.unloadModule 方法时 <mx:ModuleLoader> 组件内部就是和这个管理器进行着
通 信 , 你 可 以 直 接 访 问 ModuleManager 管 理 的 模 块 。 当 模 块 的 URL 传 递 给
ModuleManager.getModule 方法后,这个模块位置被添加到模块的管理列表中,返回一个
mx.modules.IModuleInfo 类实例。

模块实际上是 ModuleMananger 的私有 ModuleInfo 类实例。 ModuleInfo 对象加载 SWF 文件, 包
装为实现了 IModuleInfo 的代理类,并通过 ModuleManager.getModule 方法返回实例对象。你
可以监听这个代理的各种状态事件以便具体控制模块的加载。

var_moduleInfo:IModuleInfo;
_moduleInfo =ModuleManager.getModule('ContactList.swf' );
_moduleInfo.addEventListener( ModuleEvent.READY,moduleLoadHandler );
_moduleInfo.load();
用于开启加载,在加载事件中进行类型转换后,添加到界面中
private function moduleLoadHandler(evt:ModuleEvent): void
{
canvas.addChild( _moduleInfo.factory.create() as DisplayObject );
}
IModuleInfo 实现类的 unload 方法用于删除 ModuleManager 中的模块引用,但是不会删除显 示
列表中的 SWF 。要删除显示列表中的模块,你必须显示调用父对象的 removeChild 方法。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics