flex 验证-提交模式 源码解析
一、设置组件的属性
在组件里会有这样的代码:
public function set XXX(value):void{
if(this._XXX != value){
this._XXX=value;
invalidateProerties();
}
}
1.调用UIComponent类的invalidateProperties方法:
public function invalidateProperties():void { if (!invalidatePropertiesFlag) { invalidatePropertiesFlag = true; if (nestLevel && UIComponentGlobals.layoutManager) UIComponentGlobals.layoutManager.invalidateProperties(this); } }
2.如上述代码所示,高用LayoutManager的invalidateProperties方法
public function invalidateProperties(obj:ILayoutManagerClient ):void { if (!invalidatePropertiesFlag && systemManager) { invalidatePropertiesFlag = true; if (!listenersAttached) attachListeners(systemManager); } // trace("LayoutManager adding " + Object(obj) + " to invalidatePropertiesQueue"); if (targetLevel <= obj.nestLevel) invalidateClientPropertiesFlag = true; invalidatePropertiesQueue.addObject(obj, obj.nestLevel); // trace("LayoutManager added " + Object(obj) + " to invalidatePropertiesQueue"); }
3.attachlisteners方法给systemManager添加监听
public function attachListeners(systemManager:ISystemManager):void { if (!waitedAFrame) { systemManager.addEventListener(Event.ENTER_FRAME, waitAFrame); } else { systemManager.addEventListener(Event.ENTER_FRAME, doPhasedInstantiationCallback); if (!usePhasedInstantiation) { if (systemManager && (systemManager.stage || usingBridge(systemManager))) { systemManager.addEventListener(Event.RENDER, doPhasedInstantiationCallback); if (systemManager.stage) systemManager.stage.invalidate(); } } } listenersAttached = true; }
4.在触发render事件的时候,回调
private function doPhasedInstantiationCallback(event:Event):void { // if our background processing is suspended, then we shouldn't do any // validation if (UIComponentGlobals.callLaterSuspendCount > 0) return; systemManager.removeEventListener(Event.ENTER_FRAME, doPhasedInstantiationCallback); systemManager.removeEventListener(Event.RENDER, doPhasedInstantiationCallback); if (!UIComponentGlobals.catchCallLaterExceptions) { doPhasedInstantiation(); } else { try { doPhasedInstantiation(); } catch(e:Error) { // Dispatch a callLaterError dynamic event for Design View. var callLaterErrorEvent:DynamicEvent = new DynamicEvent("callLaterError"); callLaterErrorEvent.error = e; callLaterErrorEvent.source = this; callLaterErrorEvent.object = currentObject; systemManager.dispatchEvent(callLaterErrorEvent); } }currentObject = null; }
private function doPhasedInstantiation():void { // trace(">>DoPhasedInstantation"); // If phasing, do only one phase: validateProperties(), // validateSize(), or validateDisplayList(). if (usePhasedInstantiation) { if (invalidatePropertiesFlag) { validateProperties(); // The Preloader listens for this event. systemManager.document.dispatchEvent( new Event("validatePropertiesComplete")); } else if (invalidateSizeFlag) { validateSize(); // The Preloader listens for this event. systemManager.document.dispatchEvent( new Event("validateSizeComplete")); } else if (invalidateDisplayListFlag) { validateDisplayList(); // The Preloader listens for this event. systemManager.document.dispatchEvent( new Event("validateDisplayListComplete")); } } // Otherwise, do one pass of all three phases. else { if (invalidatePropertiesFlag) validateProperties(); if (invalidateSizeFlag) validateSize(); if (invalidateDisplayListFlag) validateDisplayList(); } // trace("invalidatePropertiesFlag " + invalidatePropertiesFlag); // trace("invalidateSizeFlag " + invalidateSizeFlag); // trace("invalidateDisplayListFlag " + invalidateDisplayListFlag); if (invalidatePropertiesFlag || invalidateSizeFlag || invalidateDisplayListFlag) { attachListeners(systemManager); } else { usePhasedInstantiation = false;listenersAttached = false;var obj:ILayoutManagerClient = ILayoutManagerClient(updateCompleteQueue.removeLargest()); while (obj) { if (!obj.initialized && obj.processedDescriptors) obj.initialized = true; if (obj.hasEventListener(FlexEvent.UPDATE_COMPLETE)) obj.dispatchEvent(new FlexEvent(FlexEvent.UPDATE_COMPLETE)); obj.updateCompletePendingFlag = false; obj = ILayoutManagerClient(updateCompleteQueue.removeLargest()); } // trace("updateComplete"); dispatchEvent(new FlexEvent(FlexEvent.UPDATE_COMPLETE)); } // trace("<<DoPhasedInstantation"); }
注释:
1,在组件调用invalidateProperties()方法后,调用UIComponent的invalideProperties()。
2,再调用LayoutManager的invalidateProperties()方法。
3,给systemManager添加Render事件(必需要stage.invalidate(),此事件才可以触发),在将来要更新和呈现显示列表的时候调用。
4,REnder事件被触发后,调用UIcomponent的validateProperties()方法。
5,再调用commitProperties()方法。通常在自定义组件的时候会复写该方法,将验证-提交延迟到此方法中。改写一些属性,达到局部刷新的效果。如:
override protected function commitProperties(): void { super.commitProperties(); if (sourceChanged){ if (! this.image){ image = new Image(); this.addChild(image); image.source = this._source; } else { image.source = this._source; } sourceChanged = false ; } if (scaleChanged){ this.imageWidth = this.imageWidth * this.scale; this.imageHeight = this.imageHeight *+ this.scale; scaleChanged = false ; } }
invalidateSize ----> measure和invalidateDisplayList --------> updateDisplayList和上述的过程是一样的。