FLEX4 语法及重点概要---入门篇(超详细)

来源:互联网 发布:淘宝网猎狐者户外用品 编辑:程序博客网 时间:2024/05/29 19:08

chapter 1 : intruduction to flex4

1、flex包含一个基于组件的开发模型,你只需要按需求继承现有的组件并扩展相关的方法就可开发你的应用。

 

2、可视化组件包括以下主要特性:尺寸、事件、样式、效果、皮肤。

 

3、flex定义了两套组件。一套为Spark,放在spark.*包下。一套为MX,放在mx.*包下。Spark是在flex4中新添加的,mx为旧版本中定义的。两套组件的主要不同点在于样式及皮肤的使用。另外对于容器组件,布局的方式也改变了。

 

4、有些组件在两套UI中都存中,例如按钮,在这种情况下adobe建议你使用Spark中的组件。有些组件是某套UI特有的。例如Spark中的3d效果。mx组件中的数据可视化组件,例如DataGrid、AdvancedDataGrid。所以你的应用会包含两套UI中的组件。

 

5、可视化组件的继承层次结构:Object-EventDispatcher-DisplayObject-InteractiveObject-DisplayObjectContainer-Sprite-FlexSprite-UIComponent。flex中所有的可视化对像都继承自UIComponent。

 

6、UIComponent中需要注意以下属性。doubleClickEnabled:flex默认是不支持双击的,如果要开启双击,请把该属性设为true;height:在mxml中你可以设置值为数字,这时默认单位为pix。你也可以设置为70%这种比例。在as中,如果要设置百分比,你需要用percentHeight这个属性。x,y:这组属性只在layout为绝对布局时才有效。

 

7、每一个flex组件都有对应的mxml接口和as接口。两者之间是相等的。

 

8、每个一可视化组件都包含以下三个生命周期事件:preInitialize:组件刚被创建,还没有添加子节点,且不可见。initialize:把子节点初始化好,并尺寸也设置好,但仍然处于不可见状态。 creationComplete:组件已经被放在父容器中而且可见。你可以使用上面三个事件对组件做一些初始化工作。

 

9、flex提供了多种设置组件大小和布局的机制。默认大小:如果你不指定组件的大小或布局,flex会自动设置一个适合的值。显式设置大小:你可以显式地设置组件的height/width大小。基于比例的设置大小:例如在mxml中设置height/width=70%或在as中设置percentHeight/percentWidth=70。基于约束的布局:你可通过组件中的样式属性:top,buttom等设置组件的布局及大小。这种设置方式只可以使用在父组件为绝对布局的情况。

 

10、flex应用是基于事件驱动的。事件可以让程序员知道用户与UI的交互、组件的生命周期及外观变化。当一个组件分发事件,所以对该组件进行监听的监听器都会被通知。

 

11、除了用选择器设置组件的外观外,还可以直接调用元素的setStyle("proName","value")设置外观。

 

12、flex4中的类选择器需要使用命名空间。例子代码:@namespace s "library://ns.adobe.com/flex/spark"; s|BorderContainer{borderColor:red;}。

 

13、效果(effect)是组件在一段时间内的视觉或听觉上的变化,例如退色,位移等。

 

14、数据绑定是源属性(source)发生变化时,目的(destination)属性会自动产生变化。

 

15、flex提供了三种数据绑定的方式。第一种是在mxml中使用{}括号在目的属性中对源属性进行绑定。第二种是在mxml中使用<fx:Binding>标签对源属性与目标属性进行绑定。第三种是在as中使用BindingUtils方法对源属性与目标属性进行绑定。

 

16、数据绑定符{}可以直接对属性进行引用 ,也可以对方法进行引用。例如:{obj.text.toUperCase()}

 

17、数据绑定符{}和<fx:Binding>两种方式对数据进行绑定是从编译时就开始的。而BindingUtils即在运行时才开始绑定。

 

18、可绑定符[]的意思是当对应的属性变化时,会触发数据绑定事件,通知绑定的目标属性。

 

19、当源对像分发initialize事件以及在源对像变化时都会触发数据绑定事件。

 

20、如果你创建一个对像,并想让它可以成为数据绑定的源,那属性前面必需加上[Bindable]/[Bindable("eventname")]/[Bindable(event="eventname")]标签。当你直接使用[Bindable]标签时,实质上等价于[Bindable("propertyChange")]。当属性发生改变时,flex会分发propertyChange事件给绑定于此属性的绑定目标对像。

 

21、通过<fx:Binding>标签或BindingUtils可以把多个源属性绑定到一个目标对像。绑定后,任意一个源发生改变时,目标对像都会被更新。

 

22、双向绑定,数据的任意一方发生变化时,另一方都会被通知并改变。数据绑定表达式:@{}。数据绑定标签:<fx:Binding source="" distination="destination" twoWay="true" />。另外样式、效果、RPC中的request和arguments对像都不支持双向绑定。

 

23、使用方法作为数据绑定的源。当方法的参数为[Bindable]时,参数的改变会触发数据绑定事件,让目标属性的值更新为方法的结果。如果方法中没有[Bindable]参数,即目标属性只会在开始时被更新一次。

 

24、如果你想绑定一个方法作为源数据,但该方法又没有可绑定的参数时可以使用[Bindable(event="evenname")]标签,当该对像分发dispatchEvent(new Event("eventname"))时,绑定到方法的目标属性就会被更新。

 

25、在类定义的地方便用[Bindable]标签等价于在该类中的所有public属性以及有对应的set/get方法的属性中加上[Bindable]标签。

 

27、在定义一个属性的地方使用[Bindable]标签的作用是当该属性被替换成另一个值时,目标属性会接收到通知事件,并更新值。这里要注意的是只有被替换时才更新,如果只是该属性中的某个属性被改变的情况,目标对像是不会被更新的。

 

28、在数组(ArrayCollection)中使用[Bindable]标签时,无论是数组被替换还是数组中的元素改动,都会触发更新事件。

 

29、如果只绑定数组中的某个元素时,应使用getItemAt()。这样该元素被替换时会触发更新事件去更新目标对像。但如果使用[num]的形式进行绑定时,不会触发更新事件。

 

30、在数据绑定符({})和数据绑定标签(<fx:Binding>)中,你可以使用as表达式。例如{Number(obj.text)*6/7}和ex4表达式。但不能在BindingUtils.bingProperty()/bindSetter()中使用。

 

31、as中的方法绑定接口。BindingUtils.bindSetter(funToCall,sourceObj,sourceObj.property):ChangeWatcher。

 

32、你可以使用ChangeWatcher.watch("sourceobj","sourceobj.property",listener);方法添加一个监听器,当绑定时件触发时,listener会被调用。

 

33、如果源属性被替换,但被替换的对像与原对像是同一个对像,这种情况下更新更件不会被触发。如果你想自已控制事件触发,你可以在[Bindable("eventname")]中指定事件名,然后在想更新时通过dispatchEvent(new Event("eventname"))的方式触发。

 

34、数据绑定源中的整个属性链(chain)中的每一个节点都需要[Bindable],如果只有最未端属性是Bindable,那链中的其它层属性被更改时,不会触发更新事件。

 

35、如果你把对像绑定到dataProvider的话,当你需要改变其中一个对像的一个属性时,你需要以下代码obj.dataprovider.editField(index,"propername","value");这样更新对像才会同时更新到显视组件中。

 

36、如果你把Array绑定到显视组件中时,该组件只在初始化时更新一次值。初始化后,当Array中的项改变时,不会触发更新。

 

37、容器提供了一个层次结构让你去布局组件。

 

38、flex最顶层持容器叫application。

 

39、flex容器有两种,一种是布局容器(layout container),另一种为导航容器(navigator container)。布局容器用于布局子组件/子容器的大小和位置。导航容器用于多个容器的导航。导航容器只能够到mx容器及spark的NavigatorContent容器。

 

40、mx组件容器只能存放继承自UIComponent对像的组件,而spark容器可以放下实现IVisualElement接口的组件。IVisualElement在UIComponent对像的继承层次中被实现。

 

41、mx容器与spark容器的主要区别在于mx组件的布局是固定的,而spark组件的布局是可以被替换的。

 

42、创建策略(Creation Policy)。创建策略指定了容器对子组件的初始化进程。创建策略有三个选项:ContainerCreationPolicy.AUTO/NONE/ALL。all:开始时初始化所有容器。NONE:不初始化所有子容器。AUTO:子组件在被需要时才创建,例如如果设置了AUTO选项,导航容器中除首页外,其它页的子组件在点击后才会被创建。

 

43、如果把一个容器的layout属性设为null,即该容器会采用它父容器的布局。

 

44、初始化事件顺序:preinitialize(自外向内),contentCreationComplete(容器特有,自内向外),initialize(自内向外),cteationComplete(自内向外)。

 

45、容器中有一个enabled属性,如果该属性设为false,即所有节组件都处于enabled=false状态。

 

46、容器中的defaultButton属性。设置该属性后,当用户在该容器上按回车键时,该按钮被触发。

 

47、spark中的四种布局:BasicLayout(绝对定位或约束布局),HorizontalLayout(单行水平布局),VerticalLayout(单身垂直布局),TileLayout(多行表格布局)。

 

48、spark容器中如果放置一个大于该容器的组件,默认情况下该组件会越过容器显视。

 

49、如果要把组件的显视限制在容器内,可以使用viewport和scrollbar。

 

50、viewport定义了两个区域,一个为逻辑区域(logical content),另一个为可视窗口(visible window)。逻辑区域包括所有的子组件。显视区域是用户能看见的,是逻辑区域的一个子集。

 

51、veiwport的contentHeight/contentWidth是逻辑区域的大小,它的大小由子组件决定。

 

52、height/width是可视窗口的大小。

 

53、verticalScrollPosition/horizontalScrollPosition是可视化窗口相对于逻辑窗口的坐标。坐标为负时,可视化窗口向左上移。为正时向右下移。

 

54、viewport中的clipAndEnableScrolling属性默认为false,即如果子组件的大小大于容器,那子组件将越过容器边界显视。如果设置为true,即超出容器部份将不显视。

 

55、可以通过三种方法为容器增加滚动功能:1,增加HScrollBar/VscrollBar。2,把容器放到Scroller中。3,在容器使用的皮肤中加入Scroller。

 

56、在H/VScrollerBar中设置viewport中指定该bar的目标容器。当滑动滚动条时,滚动条会改变容器的verticalScrollPosition/HorizontalScrollPosition的值。

 

57、放在scroller中的容器的clipAndEnableScrolling的值为true。

 

58、只有实现了viewport接口的容器都才能使用scroller。如果容器没实现viewport,例如BorderContainer、SkinnableContainer,即可以在此容器内放置scroller然后再放实现了viewport的容器。也可以先在scroller内先放置group,然后再放置没实现viewport接口的容器。

 

59、mx组件容器默认就支持滚动,当clipContent为true而且子组件超出容器边界时,滚动条自动出现。如果需要滚动条一直出现,可以设置horizontalScrollPolicy和verticalScrollPolicy属性为true。

 

60、显视列表中对节点的操作方法,在Spark与mx组件中是不同的。主要的不同点是spark组件的方法名中大部份含有Element,而mx组件中则以Child代替。

 

61、在显视列表中调用numElements/numChildren方法得到的是直接子节点的数目。

 

62、flex/flash有三个坐标系统:全局(global),本地(local),内容(content)。

 

63、全局坐标是以舞台(stage)的左上角为坐标原点的坐标系统。在MouseEvent中有stageX和stageY属性就是全局坐标系统中的坐标轴。

 

64、本地坐标是相对于组件左上角的坐标。所有组件都有的mouseX与mouseY属性指的是本地坐标系统的值。MouseEvent中的localX与localY也是本地坐标系统的值。而拖放操作中的xOffset与yOffset也是。

 

65、内容坐标是是相对于组件内容的左上角。与全局和本地坐标不同的是内容坐标包括组件的内容区域。组件中的contentMouseX/contentMouseY属性是内容坐标的值。

 

66、在鼠标事件中的内容坐标与本地坐标是针对事件的目标对像,而目标对像并不是一定是你操作的对像。所以一般情况下你需要把本地坐标转化为全局坐标然后再把全局坐标转化为内容坐杆。

 

67、所有的可视化组件中有关坐标的属性。contentMouseX/contentMouseY:鼠标在组件中的内容坐标。

 

68、所有的可视化组件中有关坐标的方法:contentToGlobal/contentToLocal,globalToContent/globalToLocal,locatToContent/localToGlobal。

 

69、布局(layout)分两部份,一部份为尺寸(sizing)另一部份是定位(positioning)。

 

70、布局管理器(layout manager)通过三个阶段去布局你的组件。保证阶段(Commitment pass),测量阶段(Measurement Pass),布局阶段(Layout Pass)。在保证阶段,管理器先确认你设置的组件的一些与布局有关的值。此时管理器会调用各组件的commitProperties()。在测量阶段,管理器为各组件设置或计算一些尺寸相关的属性的默认值。此阶段管理器会调用各组件的measure()方法。在布局阶段,管理器会移动和设置组件以及相关的画图方法。此时管理器会调用各组件的updateDisplayList()。

 

71、flex在程序初始化时(initializes)时或在一些与布局相关的属性改变时会自动进行布局。

 

72、在某些时候你需要手动调用组件的validateNow()方法强制进行重新布局。但此方法是计算集中型的计算,所以要确宝在需要时才调用。

 

73、布局中常用的属性。x/y:相对于父容器的左上角坐标。在绝对布局中有效。height/width:调用像素值或百分比。top,bottom,left,right:该组件相对于父容器的上下左右距离。在约束布局/流布局中常常用到。这几个属性只在绝对布局中有效。

 

74、flex布局是不考虑组件是否处于可视状态。也就是说不论组件是否可视,它都会在区域中占空间。但你可以通过includeInLayout设置组件是否参与布局。要注意的是includeInLayout只影响组件是否处于容器的布局中而不影响组件是否处于可视状态。

 

75、布局中,adobe建议采用百份比的方式设置组件和容器的尺寸。

 

76、在自动布局容器中,x/y属性的设置是不起作用的。

 

77、Spacer是一个参与布局但不可见的控件。在一些规则布局的容器中Spacer可以起到占位的作用。另外如果把spacer的宽设为100%可以起到把左边元素各左布局,把右边的元素向右布局的作用。

 

78、虽然在自动布局容器中,设置组件的x和y不会起作用。但你可以通过效果(effects)暂时改变组件的位置和大小。典型,例如当用户鼠标移动组件中,组件大小变化原来的两位并移动到容器的最前面。

 

79、在自动布局容器中,如果你把autoLayout属性设置为false,即容器不会自动布局。但此属性在mx容器中有一些情况会失效。

 

80、组件的visible控制是否可见,而includeInLayout控件组件是否参与布局。

 

81、基于约束布局常用的属性top/bottom/left/right这四个属性分别代码该组件相对于父容器的上下左右的距离。baseline代表组件中文字(标题)的底线与容器顶的距离。verticalCenter/HorizontalCenter是指组件中心与容器中心的距离。这些属性常与一些比例的尺寸使用,做到流性布局的效果。这些属性中有一些是有冲突的,例如left/right与horizontalCenter。

 

82、Application中有两个独特的事件:applicationComplete和error。applicationComplete在所有初始化工作完成后被调用。error即在httpservice调用失败后被触发。

 

83、你可以在application标签中增加一个viewSourceURL属性,并指向一个文件。在运行过程中,在应用的任何一个空白地方右击都会出现一个查看源码的菜单。

 

84、在application中还有一些属性可以设置。frameRate:帧率,帧/秒。默认值为24。pageTitle:作用和html中的title一样。preloader:指向一个自定义进度条的swc或一个类。scriptRecursionLimit:定义as调用栈的深度,默认为100。scriptTimeLimit:在fp强制停止操作前,监听器能操作的时间。默认值也是最大值为60秒。usePreloader:是否使用默认的进度条。要使用进度条,app的宽度要大于160px。另外要注意的是上面的属性只能在mxml中被设置。

 

85、flex中有两个进度条。一个为DownloadProgressBar(MX),另一个为SparkDownloadProgressBar(Spark)。你可以通过扩展以上类去实现自定义的进度条,也可以通过继承Sprite,并实现IPreloaderDisplay接口。另外需要注意一个问题,进度条应尽量小地引用类库中的类,这样可以减小进度条的大小。

 

86、为了改善性能和减小程序的大小,有一部份spark容器是不支持皮肤的。一般情况下,你使用Group和DataGroup去管理布局。使用SkinnableContainer/SkinnableDataContainer去管理布局及自定义皮肤。

 

87、关于VerticalLayout/HorizontalLayout中的verticalAlign/HorizontalALign属性。除了常规的top/bottom等对齐方式外,还有justify:设置子组件的高/宽和容器的高/宽一样。conentJustify:把全部子组件的高度设为各子组件中的最高组件的高度,或容器内容高度。

 

88、VerticalLayout.variableRowHeight:设置每一行的高度是否由各子组件确定。HorizontalColumnWidth:设置每一行的宽度是否由子组件确定。两者的默认值为ture。如果设置为false,则每一行的宽度由rowHeight决定。如果rowHeight没决定,则由VerticalLayout.typicalLayoutElement决 定。如是要各元素都很小,则宽度由第一个元素的高度决定。

 

89、控制栏(Control bar)的好处是当容器出现滚动时,控制栏的绝对位置始终不变。默认情况下,在Panel中的控制栏在panel的底部。如果需要改变控制栏的位置可以修改默认的PanelSkin。

 

90、TitleWindow是Panel的一个子类,只要用于弹出窗的使用。TitleWindow被设计为可拖放,右上角有默认的关闭按钮等。

 

91、可以使用PopUpManager.createPopUp(parent:DisplayObject,class:Class,modal:Boolean=false):IFlexDisplayObject。弹出窗口并不会阻止主窗口脚本的执行。使用removePopUp()方法移除弹出窗口。使用TitleWindow的常规流程为新建一个继承自TitleWindow的自定义组件。然后在上面定义一些事件处理。移除方法一般为PopUpManager.removePopUp(this)。的<s:TitleWindow close="PopUpManager.removePopUp(this)"。另外可以使用PopUpManager.centerPopUp(obj)的方式使弹出窗口剧中。

 

92、mouseDownOutside事件是用户在弹出窗口外点击时触发的事件。你可以使用该事件来关闭窗口。

 

93、TitleWindow与应用之间的数据交互。方法一:把在调用PopUpManager.createPopup时返回的结果转型为你的自定义组件titlewindow组件类型,然后直接调用里面的方法或属性传入相关的小组件或变量。方法二、另外也可以使用一个通用的方法。把过程信息放在一个单例或静态变量中。方法三、通过事件的方式传递数据。方法五:在组件内直接用parentApplication等属性引用父组件。上面五个方法的耦合程序不同,可重用性不同,易用性也不同。在不同的情景中可以按需求选择合适的方法传输数据。

 

94、客户端编程与服务端编程不同。服务端是多线程,多用户,所以一个类通常有多个实例。但客户端的一个类在同一时间内通常只有一个实例,此时如果用静态变量或单例可以让编程模型更简单。

 

95、dataprivider需要一个实现了IList接口的对像作为数据来源。实现了IList接口的对像有:ArrayList,ArrayCollection,XMLListCollection。

 

96、DataGroup/SkinnableDataContainer需要条目渲染器(item renderer)来显视条目。你需要配置默认的或自定义的条目渲染器来显视数据。flex提供两个默认的条目渲染器:spark.skins.spark.DefaultItemRenderer/DefaultComplexItemRenderer。

 

97、DefaultItemRenderer:对应每一个数据条目用一个label来显视。对于简单的String/Number数据可以使用DefaultItemRenderer。

 

98、DefaultComplexItemRenderer:把每一个条目放在一个单独的DataGroup中。如果数据项全是可视化组件时,可以使用这个条目渲染器。

 

99、可以通过dataProvider直接增加/删除数据。

 

100、在DataGroup/SkinnableDataContainer中使用虚拟化技术。每条数据的显视都需要一个对应的条目渲染器。当数据多时,性能会大幅下降。

 

101、使用虚拟布局(virtual layout),只为可视化的元素建立条目渲染器然后重用而不是为每个条目都建立渲染器,这种做法可以提升性能。使用虚拟布局需要把容器的useVirtualLayout设为ture。只在DataGroup/SkinnableDataContainer中的V/H/TLayout布局中支持useVirtureLayout。

 

102、可以用itemRenderer属性指定一个数据容器的条目渲染器,另外也可以使用itemRendererFunction动态决定每一个条目的渲染器。

 

103、数据容器采用条目渲染器的优先级从高到低如下:itemRendererFunctin->itemRenderer->item(如果实现了IVisualElement或DisplayObject本身。如果上面的都没有或不符合,那会报错。

 

104、可以用一个独立的文件自定义itemRender也可以直接在数据容器内实现itemRender。

 

105、List类型的控件,如果dataPrivider的数据是简单类型,如String/Number时,List会直接显视该对像。如果是复杂类型,你需要指定labelField/labelFunction或重写itemToLabel()方法。

 

106、list类组件的事件。caretChange:焦点从一个选项到另一个选项。change:选择项由手动触发变化。changing:选择项改变前发出的事件,此事件发生时可调用preventDefault()阻止选择项的变化。valueComit:编程方式触发选择项变化。以上的事件都是spark.events.IndexChangeEvent的子类。

 

107、List系统组件中支持布局的设置。这样使原来只支持垂直布局的List系列组件可以变为水平或方格布局。

 

108、List系列组件中的一些属性。requireSelection:如果为true,即List默认会把第一个选项设为被选项。如果为false,第一个选项为空。默认为false。selectedIndex:当前被选择的项的顺序,从零开始。如果requireSelecttion为false,可以把selectedIndex设为-1,表示不选中。selectedItem:当前被选中的项。

 

109、caret item意思是当前聚焦项。它可能与selectedItem为同一项,也可能不是。

 

110、List系列组件是SkinnableDataContainer的子类。SkinnableDataContainer没有默认的itemRenderer,但List系列组件有。下面是List系列组件所对应的itemRenderer。ButtonBar:ButtonBarButton;ComboBox:DefaultItemRenderer;DropDownList:DefaultItemRenderer;List:DefaultItemRenderer;TabBar:ButtonBarButton。

 

111、在List组件中,你可以把allowMultipleSelection设为true,这样用户按着ctrl键可以选择多个项。

 

112、List组件中的selectedIndices/selectedItems为被选中的序号和项,它们均为Vector对像。

 

113、ButtonBar和TabBar的作用类似于单选按钮,被点击时会发出itemClick事件。

 

114、ButtonBar/TabBar可以把一个数组付值给dataprivider。这样就是一组简单的按钮,也可以把一个mx的ViewStack付给dataPrivider。这样ButtonBar/TabBar就会直接控制这组ViewStack。

 

115、DropDownList和ComboBox的区别:ComboBox是DropDownList的子类。DropDownList就是一个纯单选的。而ComboBox除了选择外还可以手填。DropDownList中的prompt属性是没被选中时显视的文件。DropDownList的主要事件有:close/open。

 

116、在ComboBox中,如果你写入的值与集合中的不匹配,在change事件中,那selectedIndex的值为-3,对应的变量为:ComboBox.CUSTOM_SELECTED_ITEM。然后会调用ComboBox.labelToItemFunction方法把这个值转化为对像。所以如果你的集合为非简单元素,那你需要重写labelToItemFunction方法。

 

117、在一个导航容器中可以使用WideRight效果在creationCompleteEffect中。然后在各子容器中的showEffec中使用WideUp,hideEffect中使用WideDown。这样的效果比较生动。

 

118、DateChooser可以通过selectableRange设定可选日期范围,disabledRanges设置不可选日期范围,disableDays设置不可选的天。另外可以通过dayNames属性设置显视星期的文字。通过formatString可以设置日期的格式,例如:MM/DD/YYYY。另外可以通过parseFunction方法或inputFormat把输入的文字转化为日期对像。

 

119、运行时加载图片支持以下格式:GIF/JPEG/PNG/SWF。在编译时加载支持GIF/JPEG/PNG/SVG/SWF。也就是说SVG文件只支持编译时加载。另外SVG文件会受一些限制,例如不支持滤境、脚本等。

 

200、image控件中,如果想运行时加载图片,可以在source里指定路径,例如:source="url"。如果想在编译时加载图片,可以使用Embed,代码如下:source="@Embed(source='assets/logo.jpg')"。对于同一张图片,无论你引入多小次,图片也只会被加载一次。

 

201、如果不设置width/height,image默认下会以图片的大小来显视。在设置width/height的情况下,根据scaleContent的值来决定是否放大或缩小图像到width/height的大小,另外根据maintainAspectRatio来决定是否改变横宽比例。

 

202、在一幅图片中的rollOverEffect/rollOutEffect使用Reside效果会起到移到放大,离开缩小的效果。

 

203、PopUpAnchor是一个弹出控件。它的作用是把它里面的控件显视在应用的最前端而它本身没有任何外观。一般在以下几种情景中会用到:一、在页面的某个地方显视操作回馈信息。二、类似搜索引擎中的相关提示框。双击某控件时,弹出的编辑小窗口。

 

204、PopUpAnchor的displayPopUp控制它是否可见。PopUpAnchor里面组件的高宽先由popUpWidthMatchesAnchorWidth属性决定,然后是里面组件的宽度。另外可以通过popUpPosition设置组件弹出时处于PopUpAnchor的位置。如果PopUpAnchor与Effect一起使用,效果会更好。

 

205、进度条(ProgressBar)有两种,一种是显视具体进度的(Determinate),另一种是不显视具体进度的(Indeterminate)。

 

206、ProgressBar有三种模式event(默认),polled,manual。event模式会通过source属性中对应对像的progress/complete转变状态。polled模式会通过bytesLoaded/bytesTotal转变状态。manual模式会通过手动设置maxinum/mininum转变状态。

 

207、ProgressBar有一个label属性,默认值为LOADING xx%。这个属性可以手动设置,其中有四个占位符%1:已读字节数,%2:总字节数,%3:已完成的百份比,%%:%符串。

 

208、单选按钮(RadioButton),可以通过设置groupName属性把相同组的单选按钮归为一组。另外也可以定义一个<s:RadiioButtonGroup>,然后在单选按钮中设置group指定。后者的好处在于可以把相关事件设置统一设在group中。另外,RadioButtonGroup如果在mxml中定义,那要定义在<fx:Declarations>中。

 

209、NumericStepper是一个数字控件,Spinner是NumericStepper的父类,可以用click事件联合Spinner配合其它控件使用。

 

210、VideoDisplay是播放多媒体的控件,它没有边框及相关按钮。控制尺寸的属性有:maintainAspectRatio/height/width。按制播放的方法有:close/load/pause/play/stop。在VideoDisplay中可放入cuePoints(name/time)元素,同时在VideoDisplay中注册cuePoint事件,每当影片播放到指定点时,将触发cuePoint事件。如果是播放影片,可以在source属性在设置路径,如果是摄像头,可以调用attachCamera(cam)方法。

 

211、VideoPlay是拥用默认按钮的视频播放器。

 

212、flex的文件控件有五个Label、RichText、RichEditableText、TextArea、TextInput。其中前四个为多行,最后一个为单行。前两个为只读,后三个为可编辑。

 

213、MX文字控件的格式主要通过style和htmlText控制,而spark的文件控件格式主要通过FTE(Flash Text Engine)和TLF(Text Layout Framework)。

 

214、用于显视文字的主要控件有三个:Label,RichText,RichEditableText。三者中,左边最轻量级同时功能也最少,右边的相反。

 

215、在支持tlf的控件中,可以直接在控件的textFlow节点中放一下TextFlow节点。TextFlow节点下可以放置类html的标签(标签的命外空间为<s:)。另外你也可以直接设置控件的text属性,这样控件会忽略一些<p>等标签。如果你使用content属性,TLF会解悉并转化为TextFlow对像。另外你也可以使用html标签文本放在一个xml对像中,然后使用TextFlowUtil.importFromXML(xml:XML)或TextConverter.importToFlow(str:String,type:String)转化为TextFlow对像。

 

216、在mxml中相关的TLF元素如果包含一些特殊字符例如<,>等,你可以使用相关的转义字符代替,否则,你需要在相关标签中使用<![CDATA[]]>,在as中需要使用转义符/或转义。

 

217、当你需要在一个容器中放置多个相同类型的组件时,可以使用Repeater。用法是在一个容器内放置一个Repeater,然后在Repeater内放置一个组件,例如<mx:VBox><mx:Repeater><mx:Label>。Repeater需要设置一个dataprivider。而里面的组件可以通过repeater的ID.currentItem来引用当前组件代表的dataPrivider中的当前对像。

 

chapter 2 getting started

1、自定义组件命名空间格式:xmlns:Tag="包名"。例如:xmlns:MyComps:com.humanmonth.*。调用格式:<tag:ClassName />。例如:<MyComps:MyImage/>。

 

2、swc是flex组件的归档文件。

 

3、数据绑定。一、在mxml中,组件用{}引用其它数据。当被引用数据被更改时,组件的{}值也会这被更新。

 

4、flex的远程方法调用(Remote-procedure-call[rpc])用于flex与服务端交换数据(发送/接收)。flex有多种RPC服务,包括soap,amf(java),http。MXML包含以下几种类型的RPC组件:soap、httpservice、remoteobject(amf protocol)。

 

5、在mxml文件中,在<fx:Declarations>标签内定义一些非可视化组件。

 

6、数据模型(data model)。数据模型用于存储数据。可以使用标签<fx:Model>,<fx:XML>,<fx:XMLList>或as类。

 

7、用<fx:Model>定义数据模型的方法类似于直接写xml。例如:<fx:Model id="myId"><myName>tt</myName></fx:Model。

 

8、数据验证。可以在mxml的<fx:Declares>标签中声明验证器,格式:<mx:EmailValidator source="{被验证元素的ID}" property="text"/>

 

9、使用样式表(css)。如果在mxml中使用<fx:style>标签,即<fx:style>标签必需要mxml文档根元素的直接子元素。

 

10、常用的css选择器有class选择器和type选择器。使用type选择器时需要使用命名空间,语法如下:@namespace s "library://ns.adobe.com/flex/spark"; s|Button{}。

 

11、mx及spark架构中的一个主要区别是Spark组件依赖皮肤去定义布局及外观。而mx组件依赖样式及皮肤。用mx组件时,你更多地去用样式而用Spark时,你更多地是用皮肤是处理布局及外观。

 

12、使用效果(effect)。使用效果的步骤是先在<fx:Declarations>中定义一个效果,并在target中指明效果应用到的组件。然后在组件的相关事件中调用效果:effectId.play()。

 

13、用mxml自定义组件。步骤:找一个和自定义组件相近的类,然后在里面添加或修改一些方法。调用方法与actionscript的自定义组件方法一样。

 

14、在mxml中引用as中的静态变量时,使用{fullpackage.class.Name}型式。

 

15、设置默认属性(setting the default property)。很多flex组件定义一个单独的默认属性。默认属性是一种速记机制,让用户不用输入属性名的情况下设置值。例如<s:List><s:ArrayCollection>与<s:List><s:dataProvider><s:ArrayCollection>是相等的。而里面的dataPrivider是默认属性。另外要注意,并不是所有的组件都有默认属性。

 

16、在mxml中使用转义字符。若在mxml中使用字符中有数据绑定或转义符。即用正斜线转义。例如:/{,//。

 

17、换行符。你可以使用‘/n’或‘&#13;’来代表换行。

 

18、在定义一些变量前加上[Bindable]标记表示当该变量改变时,引用该变量的对像会被通知/自定修改。

 

19、引入样式或脚本的语法:<fx:Style source="url",<fx:Script source="url"。

 

20、在mxml中设置正则表达式属性:/regex/flags。

 

21、用法上,as与mxml的关系与js和html相似。而编译的角度看,as与mxml的关系和servlet与jsp相似。

 

22、无论是<fx:Script>还是<fx:Style>都必需是mxml文件根节点的子节点。

 

22、使用<fx:Script>,请在里面加上<![CDATA[]]>。

 

23、MXML中,每个元素都有一个ID属性。你可以直接通过ID引用该元素。如果元素没有设置ID,你可以通过元素的父元素的getElementAt()、getChildAt()方法获取元素。最后,你还可以通过方括号[名称]的方式来获取元素。

 

24、this是对当前文档、对像、闭包的引用。

 

25、在as中创建可视元素的步骤是:先创建元素,然后加入到容器,最后设置元素的属性。创建元素后,如果不加入到容器中,对像不会被显视。加入容器的语法是MX架构:addChild()/addChildAt(),Spark架构:addElement()/addElementAt()。

 

26、默认情况下,元素被加入到容器的最后一个元素后面。如果你要指定顺序,即需要用addElementAt()或调用addElement()后调用setItemIndex()。前者效率会高一点。

 

27、删除元素。在Spark中,可以用removeELement(),removeElementAt(),removeAllElements()方法删除元素。如果要是MX架构,即用Child替换上面的Element。

 

28、当调用容器的remove相关函数后,元素就会从显视列表中去除。然而这并不代表对像会被GC删除。紧当被删除元素在外面没有被引用时。flashGC才会在适当的时候删除对像。适时删除无用元素会大大改善性能。

 

29、只有实现了IVisualElement接口的对像才能加入到显视列表的容器中。如果对像没有实现IVisualElement接口而想加入到显视列表时,可以把对像先放到UIComponent后再加入到显视列表。例如:new UIComponent().addChild(new Sprite());

 

30、引用。FlexGlobals.topLevelApplication是对根application的引用。parentDocument是在文档链中对当前文档的上一层文档的引用。parentApplication是在应用链中对当前应用的上一层应用的引用。当被载入的应用与主应用不在同一应用域(ApplicationDomain)或安全域(SecurityDomain)时,上述引用不会生效。

 

31、在mxml中,元素的事件属性代码在mxml编译后会变成一个方法。所以在元素事件属性中的代码的this是对文档的引用而不是那个元素。

 

32、在mxml中引用as代码有两种方法,一种是<fx:Script source="pac/pac/fileName.as" />。另一种是include指令:include "filename";格式:<fx:Script>include "pac/filename.as"</fx:Script>。source支持相对或绝对路径。而include指令紧支持相对路径。include指令可放在if语句中(语句块中要求只有include指令)。

 

33、as的内省(introspection)机制有两种。它们常在调试过程中使用。一种为for in 循环。另一种为as的api。

 

34、for in循环会把动态加入的属性及方法打印出来。然后大部份的as对像并不是动态对像,所以的for in循环中,绝大部份对像不会显视属性及方法。用for in循环打印动态属性及方法与用mx.utils.ObjectUtil.toString()方法的效果一样。

 

35、内省api。flash.utils.desctibeType() 。它们打印出public属性及方法而不会打印私有的。返回的结果为一个xml。

 

36、事件可以让程序员知道事情发生。鼠标、键盘、网络请求、组件生命周期等等都会触发事件。

 

37、flash显视列表的根元素为Stage,往下为:SystemManager->Application->其它显视组件。这个列表我们称为显视列表(display list)。

 

38、显视列表的事件模型:捕获-》目标-》冒泡。即发生事件后,事件会延着显视列表树从顶层到目标然后再冒到顶层。

 

39、事件被触发时,fp(flash player)会创建一个事件对像,然后这个事件对像将在事件的三个阶段中传递。在传递过程中,事件对像的某些属性会被改变。你可能通过这些属性知道事件的所在的阶段。

 

40、flash.events.Event为事件的基类。他的子类分布在spark.events.*,mx.events.*,flash.events.*中。另外还有一些特殊作用的事件类分布在另外一些包中。例如mx.messaging.events

 

41、显视列表中的任何对像都继承自DisplayObject,而DisplayObject继承自EventDispatcher。EventDispatcher为显视列表中的所有类提供了事件模型的功能。

 

42、显视列表中的任何对像都可以通过继承自EventDispatcher的addEventListener来监听事件。只要事件流通过该对像,该对像的监听器都会被触发。

 

43、EventDispatcher从名称上说,主要功能为分发事件。但在使用过程中,更多是用于添加与移动监听事件。

 

44、当你需要事件模型中的功能,但又不能继承EventDispatcher时,可以实现IEventDispatcher接口。

 

45、除了由fp发送事件对像外,有些时候你可能需要自已发送事件。这时你可能通过dispatchEvent方法发送自定义事件到事件流中。

 

46、event对像中的target为触发事件的对像。currentTarget为正在处理事件的对像。

 

47、在mxml的元素中的事件属性直接添加事件时,如果使用click=functionname()时,event对像不会被传入到方法中。如果要传入event对像,需要click=functionname(event);

 

48、addEventListener中的use_capture参数为true时表示监听器在捕获阶段被调用,如果为false表示在冒泡阶段被调用。如果不指定,那默认值会根据事件类型的不同而不同。如果你需要在事件的两阶段都解发事件,那你需要调用两次addEventListener。use_capture参数一次为true,另一次为false。

 

49、addEventListener中的priority。如果不设置,priority默认值为0。这种情况下,先调用addEventListener的监听器会先被调用。如果设置了priority,即priority的值越高,越早被调用。

 

50、addEventListerer中的weakRef。默认为false。如果此值为false,即此监听器不会被GC回收。如果为true,此监听器会被GC回收。

 

51、方法闭包在每次被调用时都会被创建。闭包的作用域在定义它的地方而不在调用它的地方。例如,闭包内引用外面的一个变量y,在调用它的方法外面也有一个变量y。即运行时,闭包引用的是定义的类中的y。

 

52、在addEventListener中使用闭包时,参数中的userWeepRef如果设为true,在gc运行时可能会把闭包回收。这样会出现不可预期的错误。

 

53、类级别的定义不会被GC回收,闭包除外。

 

54、使用addEventListener设置的监听器不再被使用时,应该用removeEventListener移除。而在mxml中直接给onclick付值的方式增加的监听器不能被移除。

 

55、为一个对像的同一种类形事件添加多个触发器的方法:在mxml的事件属情中有分号隔开多个监听器。例如:listener1();listener2()。或者利用addEventListener多次:obj1.addEventListener(click,m1);obj1.addEventListener(click,m2);

 

56、在监听器中实现多个参数。由于addEventListener参数中的function是一个方法,且参数固定为event。如果要实现监听器多参数,方法有三个。一、闭包。因为闭包中变量的作用域是定义它的地方。例如:obj.addEventListener("click",function(event){fun(p1,p2)}。二、在mxml的标签属情中设置监听器,因为在mxml中设置监听器时,参数是随意的。例如click="fun(event,p1,p2)"。三、把参数放在currentTarget对应的对像中。在实际使用过程中,第三种方法最简单。

 

57、手动分发事件。由于UIComponent->DisplayObject->EventDispatcher。所以显视列表中的所有对像都有dispatchEvent()方法。例如:obj.dispatchEvent(new Event("click"));

 

58、显视列表中的大部份对像的事件都经历事件模型中的三个阶段(捕获、目标、冒泡)。而不在显视列表中的对像也具有相同的事件模型,但只有(目标)阶段,例如socket的响应。另外, 在显视列表中的格式对像、验证对像也同样只有目标阶段。

 

59、默认情况下,所有的监听器都只注册在目标及冒泡阶段,除非你手动注册一些在捕获阶段的监听器-addEventListener("click",func,true);

 

60、当你在一个对像中监听一个click事件。当该监听器响应时,并不一定代表是该对像dispatch的。很多情况下是该对像下的子对像触发的。所以要区分好event中的target及currentTarget。

 

61、stopProgragation()与stopImmediatePropagation()的作用都是停止事件的传递,前者是阻止节点后面的事件被调用。后者是阻止当前节点当前事件往后的事件被调用。

 

62、无论是stopProgragation()还是stopImmediatePropagation()都阻不了默认事件的执行。例如Event.Close等。

 

63、在一群组件中调用addEventListener注册同一个方法的效率比较低(性能与内存)。可以考虑把方法注册在父组件中。例如在流程图中有一大群节点。如果在所有节点中都注册一些移动事件,这样效率很低下。可以考虑把事件注册在容器中,然后从target中获取标识。再使用container[pre_id]获取组件。这种做法可以加快应用的启动速度及减小内存占用。

 

64、一般把监听键盘的任务放在最外层容器中。这样可以统一管理。例如:FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_UP,fun)。另外需要注意,在app初始化后,FlexGlobals.topLevelApplication并不接收事件,你需要让其中的任一个组件聚焦后,它才会接收到事件。

 

65、keyCode与charCode的区别在于keyCode代表键盘上的一个键,而charCode代表该键产生的utf8的一个值。例如k与K的keyCode是相同的,而charCode不同。

 

66、判断组合键的方法。例如判断是否为shift+q:if(event.shiftKey){if(event.keyCode==81){}}。

 

67、关于操作系统、浏览器与fp接收事件的顺序。os第一,浏览器第二,最后才是fp。所以当浏览器拦截了事件并关阻止事件后,fp会收不到事件。

 

 

chapter 3:application architecture

1、默认情况下,swf文件只能向swf文件所在的域提出http或其它网络请求。如果要仿问swf文件所在的不同的域,即要在目标域的根目录中放置一个crossdomain.xml文件,设置当前服务器接受的域。

 

2、mxmlc可以把mxml、as、swc、rsl等文件打包成一个swf文件,而compc可以把mxml、as等编译成swc或rsl文件。

 

3、部署文件时,请确保rsl等资源文件是否存在于服务器中以及swf文件指向的rsl的路径。

 

4、flashbuilder使用swfobject2类库把swf放在html中。

 

5、在网络安全沙箱内,flash除了ShareObjects外,不能访问本地的磁盘及资源。在得不到用户允许的情况下,不能从摄像头或耳麦中获取信息并发送到网络。

 

6、swf只能访问网络或本地资源两种中的一种。也就是说要么你把swf设置为只能访问网络,要么把swf设置为只能访问本地资源。设置的选项为编译时的use-network=true/false。默认为true。

 

7、flex只持基于组件的开发模型。常规的开发方法是先扩展一些基本的UI组件并把你需要的功能封装在上面,然后再在UI中组装起来。

 

8、在开发过程中,你会使用自已开发的自定义组件或外部的自定义组件。默认情况下flashbuilder在项目src及其子目录下寻找自定义组件。如果你需要使用别的地方的自定义组件,你可以设置source path。flashbuilder除了在src目录下寻找组件外,还会在source path下寻找自定义组件寻找的顺序按source path顺序寻找。在as中引用组件,使用import语句。在mxml中,使用命名空间。

 

9、swc文件是flex的打包文件,常用的as/mxml通用组件会打包成swc文件。通过library-path可以加载swc文件。

 

10、swf文件被客户端下载后只保存在浏览器的缓存中,浏览器关闭后,swf文件可能会被删除。从swf文件中分离出swc文件以rsl的形式加载可以减swf的体积以及减小每次的下载量。在编译时可以使用runtime-shared-libraries选项指定rsl的位置。

 

11、可以把flex应用分成多个模块(modules)。编译后,原来的一个swf文件变成多个swf文件,主swf文件在需要时才加载或卸载模块。

 

12、在flashbuilder中你可以通过修改配置文件或直接设置command-line argument给编译器。

 

13、flex编译器是区分大小写的。

 

14、swf只能访问自已域保存的ShareObject文件。默认情况下ShareObject的大小为每个域100k。如果要使用大于100k,程序需要弹出询问对话框。另外当大于100k时,fp会自动弹出对话框,询问用户是否允许超过100k的大小。

 

15、fp会自动监控程序占用内存及cpu的情况。如果要长时间占用大量资源,fp会自动询问用户,是否需要关闭应用。

 

16、fp不会把客户端的一些私密信息提供给app,例如:帐户、电话、mail等。但为了提高app的用户体验,fp会提供user agent,系统兼容性(语言,mp3编码),是否有摄像头,麦克风。另外fp还可以设置剪帖板的信息,但不会提供获取剪帖板信息的方法。

 

17、flash有四种沙箱类型。同一个swf文件在不同的沙箱中有不同的安全限制。

 

18、远程沙箱(remote)。所有来自非本地URL的文件(html,swf2html脚本)被放到远程沙箱中。swf按不同的域被分到不同的沙箱中。

 

19、本地文件系统沙箱(local-with-filesystem)。本地文件系统沙箱是本地swf文件的默认沙箱。在此沙箱中的swf文件不能访问远程主机。

 

20、本地网络沙箱(local-with-networking)。本地文件系统沙箱是本地的swf文件具有仿问网络的权限,但不具备访问本地文件的能力。

 

21、本地信任沙箱(local-trusted)。在这个沙箱中的swf没有权限限制。所有本地的swf文件都可以设置成这种沙箱。设置这种沙箱可以通过交互的方式设置(Settings Manager)或能过非交互方式设置(通过安装程置增加配置文件)。

 

22、可以使用编程的方式读取Security中的sandboxType属性查看沙箱类型。

 

23、编译时的use-network参数及swf下载的地方可以决定沙箱类型。本地的swf文件的use-network设置为ture是,沙箱类型为local-with-network,设置为false时为local-with-filesystem。远程下载的swf文件的use-network设置为true时,沙箱类型为remote,设置为false时会报错。

 

24、fp客户端有四种类型。分别为浏览器嵌入式的正式版及调试版和独立版的正式版及调试版。

 

25、fp的浏览器嵌入式客户端在不同的浏览器中以不同的技术实现,在IE中以ActiveX,在其它浏览器中以plug-in实现。在浏览器嵌入式客户端时可以使用一些浏览器技术,例如form及ssl。

 

26、DisableLocalSecurity打开时,swf处于本地信任(local-tursted)安全沙箱中。EnforeLocalSecurity打开时,swf处于其它的三种沙箱中。默认情况下,ActiveX控件是DisableLocalSecurity,plug-in默认为EnforeLocalSecurity。

 

27、交互脚本(cross-scripting)。两个不同的swf文件需要相互访问时需要使用cross-scripting。只有处于同一个安全沙箱中的swf文件才能使用交互脚本。也就是说当swf处理不同类型的安全沙箱,或处于同一类安全沙箱,但swf文件来自不同域时都不能使用cross-scriptin。

 

28、来自不同域的两个swf文件需要cross-script时,可以通过设置Security.allowDomain/allowInsecureDomain方法设置swf文件可以被哪些域仿问。

 

29、flash.net.Externallnterface是调用外部js(call)及设置被js调用接口(addCallback)的主要类。ExternalInterface的调用权限由包装它的html设置,主要参数有:allowScriptAccess和allowNetworking。默认情况下,externalInterface被允许调用同域的js。

 

30、navigateToURL()主要用于打开或替换当前窗口,也可以用于调用外部js。它同样受限于allowScriptAccess和allowNetworking参数的限制。

 

31、由浏览器打开的swf文件以及在swf中的图片相关资源会存放于浏览器的缓存中。这些文件在浏览器关闭后也有可能同样保留在缓存中。所以你可以通过http报头设置当浏览器关闭时清空这些缓存:cache-control:no-cache,no-store,must-revalidate,max-age=-1 pragma:no-cache,no-store expires:-1

 

32、可信任的网页及目录。浏览器本身有一个安全模型。fp会与浏览器的安全模型交互,如果浏览器把一个网页设为可信任的网页,即fp会把该网页下的swf文件处于可信任的安全沙箱(local-trusted)中。另外用户通过fp的User Settings Manager或增加一个FlashPlayerTrust Configuration文件指一个可信任目录,然后把swf文件放到该目录下。当打开该swf文件时,该文件也处于可信任安全沙箱中。

 

33、部署过程中,如果你的swf及资源文件发布在不同的域中。你除了需要增加crossdomain.xml文件以及在app中调用allowdomain等外。最好还需要把一些通配符(*)设置成具体的域和端口。

 

34、fp是区分获取内容(Content)与获取数据(Data)的。Content与Data的区别是Content一般只用于显视,而Data可被as处理。获取内容会比获取数据的限制小一点。在不同域中获取的数据或swf文件会被放到不同的沙箱中。

 

35、向远程读取图片用于显视时,一般不受限制。但从远程读取数据时例如xml时,需要得到远程的授权及html的受权。

 

36、LocalConnection可以让在同一客户端电脑上的各个swf之间进行方法调用。在调用过程中,一个swf称为sender,另一个称为listener。最简单的情况是同一个域中的两个swf之间的调用。在不同域之间调用需要调用LocalConnection.allowDomain()/allowInsecureDomain()方法。

 

37、swf是一种开发格式。所以它可能被反编译,里面的信息会被别人看到。所以发布产品前应该放在里面的敏感信息去调。

 

38、为了做到安全,你应该注意以下几点:一,不要把敏感信息,例如帐户放在swf内。二、用户授权验证、sql等应放在服务端完成。三,如果在使用过程中,swf与server之间传递敏感信息,可以考虑使用ssl。

 

39、安全相关的错误事件并不是由目标对像发出来的。所以并不能用常规的.addEventListener方法去处理错误而是使用try{}catch(e){}方法是铺捉。

 

40、当你使用TextArea或TextInput来输入密码时,请把里面的displayAsPassword属性设置为true。

 

41、在浏览器中打开一个flash后,可以右击-设置。然后对一些权限进行设置。

 

42、模块(Module)是一个SWF文件。它可以被一个或多个app调用,但不能单独运行。

 

43、模块比RSL更灵活。它是否被加载由app决定,并且在编译时不需要被引用。

 

44、模块域(Module Domains)。默认情况下,模块被加载到主app的子域中。这样出现的问题所有模块所在域都从属于主域,但模块间的域就不相同而且没有从属关系。当一个模块调用一些Manager类后,例如(PopoupManager、DragManager),另一个模块再调用这些管理类时将出错。因为那些管理类属于它们被第一次调用的域。要解决这个问题的做法是在主app中,初始化这些管理类,然后这些管理类就可以被各模块共用。

 

45、如果要获取最好的交互性,主app与所有模块最好处于相同的安全沙箱中。

 

46、创建模块的步骤。一、mxml:根元素为<mx:Module>,as:继承Module/ModuleBase。二,像一般应用一样编译它。三、通过<mx:ModuleLoader>标签或ModuleLoader/ModuleManager类去加载模块。

 

47、每个模块都有它自已的IStyleManager2实例,也就是说每个模块都有它自已的样式。各模块之间的样式不会相互影响。在主app加载完模块后,模块的样式会与主app的样式合并,合并的最终结果是模块的样式优先级高于主模块。

 

48、当你在编译模块时使用了isolate-style=false选项时,各模块间将会共用一个样式。如果模块间有相同的样式,即先被加载的样式的优先级会高于后加载的模块样式的优先级。使用该选项后,可能会出现卸载模块后模块不被GC回收等一些情况,因为有些模块的样式可能被其它模块引用。

 

49、getStyleDeclarations()只返回定义的样式,要获取合并后的样式需要调用getMergedStyleDeclaration()。运行间设置样式定义只会影响定义的样式,该样式是否起作用取决于合并样式。

 

50、StyleManager可用于设置所有元素的样式。语法如下:StyleManager.getStyleDeclaration("spark.components.Button").setStyle("fontSize",15);

 

51、模块的开发方法就像app开发方法一样,可以使用mxml或as。模块可以被模块或app加载。

 

52、ModuleLoader提供了高层次的加载接口,而ModuleManager提供了加载模块的底层接口。

 

53、当你的模块要用于显视或用到framework的类,你可以用<mx:Module>标签或继承Module类。如果你的模块不用显视和framework类,你可以考虑用as继承ModuleBase类。这样的模块体积会减小。

 

54、默认情况下Module编译后会包含所有它依赖的类:框架及自定义的类库。结果就是主类加模块的体积远比单独的app大。

 

55、在flashbuilder中可以选择项目-属性-module然后选择模块所属主类,这样flashbuilder可以优化模块的大小。

 

56、当一个模块中的类想用另外一个模块中的类,那就要把模块中的类的模块域提高到app中。

 

57、如果在air中使用模块。那模块必需和主类在同一目录或在主类的子目录中。

 

58、ModuleLoader语法。<mx:ModuleLoader url="com/humanmonth/ColumnCharModule.swf"/>。你需要设置的主要是url。你可以在需要时才设置url,设置后fp才会去加载它。当你设置或重新设置url时会触发ModuleLoader的loadModule()方法,当你把url设置为“”,ModuleLoader会卸载模块。另外你也可以手动调用ModuleLoader的loadModule/unloadModule方法。

 

59、无论你调用多少次loadModule(),fp保证对一个module,一个ModuleLoader只会加载一个实例。

 

60、ModuleManager提供了低层次的加载module的接口。在用ModuleManager加载接口时要注意,module对像要放在类属性中,以免被GC回收。

 

61、如果模块分散在不同的服务器中。你需要解决一些权限问题。Security.allowDomain("remoteservername");Security.loadPolicyFile("Http://remoteservername/crossdomain.xml");new URLLoader(new URLRequest("http://remoteservername/crossdomain.xml"));loader.load(request);

 

62、把一个app分开多个module的一个好处是主app的尺寸变小了,第一次加载app的时间缩短。但另一个问题是当用户使用到模块时,模块加载也需要时间。解决这个问题的一个途径是预加载模块。预加载模块的

代码:var info:IModuleInfo=ModuleManager.getModule("url");info.addEventListener(ModuleEvent.READY,fun);info.load();

 

63、ModuleLoader就很多事件。你可以扩展它实现自定义的加载类,例如增加一些显视加载进度,图片等效果。让整个系统有一个统一的加载效果。

 

64、通过相关属性引用实现app与module间方法相互调用。这种方法会造成app与module的强耦合和因为代码的引用使得app与module的尺寸增大。但好处是简单直接。方法如下:一,ModuleLoader.child属性。代码:(moduleloader1.child as ChildModule1).fun。二,如果你用ModuleManager加载模块,可以通过以下代码获取模块module.factory.create() as MyModule。三,通过module.parentApplication方法引用父应用。四,模块间调用,先用module.parentApplication得到父应用再调用相应的child或factory属性。

 

65、通过模块的url参数传递数据。 module中有一个loaderInfo属性,里面可以获取调用它的url。你可以从字符串中找到信息。

 

66、模块与app间的相互调用最灵活的方式是让app或module实现自已定义的接口,然后把app或module转型为接口后调用。这样app与module间处于低耦合状态。

 

67、使用子应用(sub-applications)有以下好处:减小主应用的体积;按功能封装代码;增加可重用性;整合第三方子应用。

 

68、对主应用来说,子应用分为可信子应用和不可信子应用。当主应用与子应用基于相同版本的库架构建时具有良好的交互性。如果子应用的库版本较主版本的低,即交互性有一定的限制。

 

69、子应用的可信级别及版本取决于应用域(application domain)及安全域(security domain)。

 

70、有三种类型的子应用:1,单版本应用。2,多版本应用。3,沙箱应用。

 

71、应用域(application domain)是存放类定义的一个容器【类似于java的classloader】。一个应用有一个顶层应用域-system domain。应用域是system domain的一个子域。当你载入一个子应用时,你可以选择把它载入三种域:兄弟域(sibling application domain),子域(child application domain),当前域(current application domain)。

 

72、默认情况下SWFLoader/Loader控件把子应用载到子域中。如果当前应用与子应用所基于的类库版本不同时,载入后会出现错误。如果主与子应用基于不同的库版本,你应该把子应用载入到兄弟域中。

 

73、使用SWFLoader加域子应用时,把loadForCompatibility属性设置为true时,SWFLoader会把子应用加载到兄弟域中,反之,加载到子域中。

 

74、system domain是最顶层的域。共用的域(playerglobal.swc)被加载到此域中。父域已经存放的类定义,子类不会重复加载。

 

75、基于不同版本类库的应用应加载到兄弟域中,否则会出错。

 

76、一般RSL与编译时的资源会被加载到当前域中,SWFLoader一般不会把子应用加到当前域。

 

77、安全域定义了应用的可信级别。多个应用的可信程序越高,它们的交互性越强。

 

78、如果子应用与主应用属于相同域名下载的,默认情况下它们处于同一个安全域。反之,需要设置SWFLoader的trustContent为true让两者处于相同的安全域。

 

79、沙箱应用(sendboxed applications)之间有很多限制。包括不能仿问state对像,不能接收mouse事件,不能调用其它app的画图,不能访问访问其它app的一部份属性。

 

80、大应用、混合编程、一些工具类都会使用子应用的方式加载。

 

81、沙箱应用(sandboxed application)。当你需要加载一些不可信的第三方swf文件,且主swf与子swf所依赖库的版本不一致。这种情况下把子swf以兄弟域的型式加载到主swf中。我们把这种情况叫沙箱应用。

 

82、上面所提及到的所有类型的子应用都应符合条件:主应用依赖的库要比子应用依赖的库新或相同。

 

83、主app加载来自不同域名的子app的情况,我们称为import loading。

 

84、采用模块与子应用有以下区别:因为模块与主应用共享类定义,所以文件尺寸会小一点。模块与主应用的耦合性高一点。模块与 主应用要使用同一版本的库而子应用没这个要求。模块一般会在主应用的子应用域中,所以管理类共享。模块只能加载到主应用的子应用域中,而子应用可以载进主应用的兄弟应用域或子域。模块只能放进安全模,而子模块既可放进安全域也可放进不安全域。

 

85、SWFLoader与Loader的区别。SWFLoader是Loader上的一个封装,使用起来更简单,且提供了一些额外功能,例如支持样式与效果,可以监控加载进度,被加载的swf文件可以是多版本的。

 

86、夸域交互时,建议采用事件机制进行。

 

87、沙箱应用与多版本应用在编译时应加上以下参数:-include=mx.managers.systemClasses.MarshallingSupport。

 

88、子应用可以独立运行。它不应依赖主应用以及兄弟应用。

 

89、设置SWFLoader时可以单独设置loadContext或直接设置loadForCompatibility和trustsContent。loadContext的优先级要高于后者。以上属性应SWFLoader加载前设置。

 

90、LoadContext对像有两个属性,一个为securityDomain另一个为applicationDomain。如果不设置securityDoamin时,子应用会采用它自已的的安全域。如果要把子应用设置成可信域,即使用以下语句:context.securityDomain=SecurityDomain.currentDomain。设置applicationDomain时可以设置三个值:new ApplicationDoamin():兄弟域,new ApplicationDomain(ApplicationDomain.currentDomain):子域。application.currentDomain:当前域。最后要注意的是同一个LoadContext不要用于加载多个应用。

 

91、卸载子app时可以使用loader.unloadAndStep(true)或loader.source=null。另外,当loader再load一

 

个子app时,上一个app会被自动卸载。

 

92、在可信任的单版本的子app中,子app可能通过application或parentDocument访问主app。

 

93、主app访问子app的方法:(contentLoader.content as SystemManager).application as SubApp2。

 

94、如果主应用要加载子应用中的类,那子应用一定要和主应用处在同一个安全域及相同的版本。加载的方法为new UIComponent(new (loader.loaderContext.applicationDoamin.getDefinition('ClassName') as Class)());。访问相关属性 obj['property']。 

 

95、在sandboxed application中,除了FocusManager外,其它的Manager,例如DragManager、ToolTip、Alert、指针等的效果都只在子app中出现,主app不受这些效果的影响。

 

96、相同安全域的主从应用可弹出框、ToolTip、鼠标不限于子应用区域。

 

97、Bootstrap 是一个轻量级的类容器。它先于主应用被加载,所以由它加载的类可以在各应用在共享。一般情况下,一个安全域可以用一个bootstrap。因为bootstrap加载的类不能在不同的安全域间共享。

 

98、如果子应用需要使用rpc,那rpc相关类一般会由Bootstrap加载。

 

99、BABridge(Flex Ajax Bridge)是一个简单的类库,用于js与as间的相互调用。利用ExternalInterface类也可以实现相关功能,但需要编写复杂的代码及限制比较多。

 

100、BABridge的地址在sdk_installation_dir/frameworks/javascript/fabridge下。如果你使用FlashBuilder,你可以直接右击项目,选择:Create Ajax Bridge。你需要在mxml中加入<fab:FABridge xmlns:fab-"bridge.*"/>。完成后,你就可以在js中直接使用FABridge.flash.root()引用flash的主类。

 

101、获取加载swf人url人代码:mx.core.FlexGlobals.topLevelApplication.url。

 

102、获取客户端信息的类:flash.system.Capabilities。从中可以获取客户端操作系统,播放器,语言等。

 

103、ExternalInterface是as与js互相调用的主要类。其中主要方法有两个:call()/addCallback()。ExternalInterface受安全沙箱的限制,它受限于swf的引入代码中allowScriptAccess/allowNetworking属性的值。

 

104、在初始化阶段,我们一般需要向swf文件传一些参数。我们可以通过htmlwraper中的flashVars、swf的url参数、swf初始化后通过ExternalInterface调用js获取页面中的参数。三者相比,通过url传参比较简单。

 

105、通过静态方法ExternalInterface.call(funName,para... paras)调用js。

 

106、flash.net.navigateToURL()可用于调用js,也可用于打开新窗口。

 

107、URLLoader用于后台向服务器发出请求,而navigateToURL()用于调用浏览器的窗口加载页面。

 

108、navigateToURL(req:URLRequest,window:String)用法。window的值所代表的意思:_self:在本窗口打开,_blank:本窗口之上弹出,_parent:在父窗口打开,_top:最顶层窗口打开。

 

109、navigateToURL调用js:navigateToURL(new URLRequest("javascript:fun()","_self");

 

110、在swf的html包装器中allowScriptAccess的选项有三个:never,sameDoamin,always.

 

111、一些公用的类加、资源可以打包成RSL(Runtime Shared Libraries)。RSL被下载到客户端后可以被多个应用共享使用。

 

112、有三种类型的RSL:Framework:官方标准库,可被任意应用使用。Standard:自已打包的应用,可被相同域的应用使用。Cross-domain:在Standard的基础上可被任意域使用。Framework与后两者的另一个区别在于签名的Framework(swz)存放在fp相关目录下,而后两者存放在浏览器的缓存中。另外要注意的是非签名的framework(swf)也存放在浏览器缓存中。

 

113、flex编译时分静态链接与动态链接两种。如果使用静态链接,flex在编库时把相关库和应用打包成一个文件。静态链接的特点是文件很大。与静态链接相关的编译参数为有四个library-path,include-libraries,includes,source-path。前面四个参数中包含include关键字的参数是把关联的所有库打包进主应用中,而没有include的是把相关联的类打包进主应用中。动态链接是让应用在需要用到相关类时才加载。模块、运行时样式表、RSL都使用动态链接技术。在flash builder中你可以从Project-Properties-Flex Build Path-Library Path中 设置link Type。

 

114、使用动态链接时,需要在编译中加入参数:runtime-shared-library-path,runtime-shared-libraries,external-library-path,externs,load-externs。

 

115、sdk/frameworks/libs下以swc结尾的库为编译时使用的。sdk/frameworks/rsls下以swf结尾的为unsign库,swz结尾的为sign库。

0 0