我有一个带有皮肤的Spark TextInput。此Skin有3种状态,需要能够根据收听的事件更改状态。
TextInput的持有者是一个Panel,当用户点击某个地方时会发送一个事件。
我不知道怎么听这样的事。
Panel中的textInput:
<s:TextInput id="nombre" x="10" y="23" width="264" borderVisible="false"
chromeColor="#791111" color="#741111" contentBackgroundColor="#ECECEC"
focusColor="#6E1212" fontWeight="bold"
skinClass="skins.NormalInputText"
text="@{clientesModel.datosCliente.nombre}"/>
和Skin NormalInputText:
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
alpha.disabledStates="0.5" blendMode="normal" currentState="normal"
creationComplete="init()">
<fx:Metadata>
<![CDATA[
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.TextInput")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
import mx.core.FlexVersion;
private var paddingChanged:Boolean;
/* Define the skin elements that should not be colorized. */
static private const exclusions:Array = ["background", "textDisplay", "promptDisplay", "border"];
/* exclusions before Flex 4.5 for backwards-compatibility purposes */
static private const exclusions_4_0:Array = ["background", "textDisplay", "promptDisplay"];
public function init():void {
parent.addEventListener('panel_mode_edit', editMode);
parent.addEventListener('panel_mode_query', queryMode);
parent.addEventListener('panel_mode_new', newMode);
}
private function editMode(evt:Event):void {
this.currentState = 'editing';
}
private function queryMode(evt:Event):void {
this.currentState = 'normal';
}
private function newMode(evt:Event):void {
this.currentState = 'adding';
}
override public function get colorizeExclusions():Array {
// Since border is styleable via borderColor, no need to allow chromeColor to affect
// the border. This is wrapped in a compatibility flag since this change was added
// in Flex 4.5
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_5)
{
return exclusions_4_0;
}
return exclusions;
}
/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
static private const contentFill:Array = ["bgFill"];
/**
* @private
*/
override public function get contentItems():Array {return contentFill};
/**
* @private
*/
override protected function commitProperties():void
{
super.commitProperties();
if (paddingChanged)
{
updatePadding();
paddingChanged = false;
}
}
/**
* @private
*/
override protected function initializationComplete():void
{
useChromeColor = true;
super.initializationComplete();
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (getStyle("borderVisible") == true)
{
border.visible = true;
shadow.visible = true;
background.left = background.top = background.right = background.bottom = 1;
textDisplay.left = textDisplay.top = textDisplay.right = textDisplay.bottom = 1;
if (promptDisplay)
{
promptDisplay.setLayoutBoundsSize(unscaledWidth - 2, unscaledHeight - 2);
promptDisplay.setLayoutBoundsPosition(1, 1);
}
}
else
{
border.visible = false;
shadow.visible = false;
background.left = background.top = background.right = background.bottom = 0;
textDisplay.left = textDisplay.top = textDisplay.right = textDisplay.bottom = 0;
if (promptDisplay)
{
promptDisplay.setLayoutBoundsSize(unscaledWidth, unscaledHeight);
promptDisplay.setLayoutBoundsPosition(0, 0);
}
}
borderStroke.color = getStyle("borderColor");
borderStroke.alpha = getStyle("borderAlpha");
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
/**
* @private
*/
private function updatePadding():void
{
if (!textDisplay)
return;
// Push padding styles into the textDisplay
var padding:Number;
padding = getStyle("paddingLeft");
if (textDisplay.getStyle("paddingLeft") != padding)
textDisplay.setStyle("paddingLeft", padding);
padding = getStyle("paddingTop");
if (textDisplay.getStyle("paddingTop") != padding)
textDisplay.setStyle("paddingTop", padding);
padding = getStyle("paddingRight");
if (textDisplay.getStyle("paddingRight") != padding)
textDisplay.setStyle("paddingRight", padding);
padding = getStyle("paddingBottom");
if (textDisplay.getStyle("paddingBottom") != padding)
textDisplay.setStyle("paddingBottom", padding);
if (!promptDisplay)
return;
padding = getStyle("paddingLeft");
if (promptDisplay.getStyle("paddingLeft") != padding)
promptDisplay.setStyle("paddingLeft", padding);
padding = getStyle("paddingTop");
if (promptDisplay.getStyle("paddingTop") != padding)
promptDisplay.setStyle("paddingTop", padding);
padding = getStyle("paddingRight");
if (promptDisplay.getStyle("paddingRight") != padding)
promptDisplay.setStyle("paddingRight", padding);
padding = getStyle("paddingBottom");
if (promptDisplay.getStyle("paddingBottom") != padding)
promptDisplay.setStyle("paddingBottom", padding);
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
var allStyles:Boolean = !styleProp || styleProp == "styleName";
super.styleChanged(styleProp);
if (allStyles || styleProp.indexOf("padding") == 0)
{
paddingChanged = true;
invalidateProperties();
}
}
]]>
</fx:Script>
<fx:Script>
<![CDATA[
/**
* @private
*/
private static const focusExclusions:Array = ["textDisplay"];
/**
* @private
*/
override public function get focusSkinExclusions():Array { return focusExclusions;};
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="editing" />
<s:State name="adding" />
<s:State name="disabled" stateGroups="disabledStates"/>
<s:State name="normalWithPrompt"/>
<s:State name="disabledWithPrompt" stateGroups="disabledStates"/>
</s:states>
<!-- border -->
<!--- @private -->
<s:Rect left="0" right="0" top="0" bottom="0" id="border">
<s:stroke>
<!--- @private -->
<s:SolidColorStroke id="borderStroke" weight="0" />
</s:stroke>
</s:Rect>
<!-- fill -->
<!--- Defines the appearance of the TextInput component's background. -->
<s:Rect id="background" left="1" right="1" top="1" bottom="1">
<s:fill>
<!--- @private Defines the background fill color. -->
<s:SolidColor id="bgFill" color="#ebebeb" />
</s:fill>
</s:Rect>
<!-- shadow -->
<!--- @private -->
<s:Rect left="1" top="1" right="1" height="1" id="shadow">
<s:fill>
<s:SolidColor color="0x000000" alpha="0.12" />
</s:fill>
</s:Rect>
<!-- text -->
<!--- @copy spark.components.supportClasses.SkinnableTextBase#textDisplay -->
<s:RichEditableText id="textDisplay"
verticalAlign="middle"
widthInChars="10"
color.normal="#999999"
color.editing="#29ABE2"
color.adding="#D67A1E"
left="1" right="1" top="1" bottom="1" />
<!--- Defines the Label that is used for prompt text. The includeInLayout property is false so the prompt text does not affect measurement. -->
<s:Label id="promptDisplay" maxDisplayedLines="1"
verticalAlign="middle"
mouseEnabled="false" mouseChildren="false"
includeIn="normalWithPrompt,disabledWithPrompt"
includeInLayout="false"
color.normal="#999999"
color.editing="#29ABE2"
color.adding="#D67A1E"
/>
我使用parent.addEventListener('panel_mode_edit',editMode);听取这个事件,但它不起作用。
怎么了?
更新:
调度事件:
panelClientes.dispatchEvent(new Event("panel_mode_query", true, true));
在TextInput Skin中:
public function init():void {
hostComponent.addEventListener('panel_mode_edit', editMode);
hostComponent.addEventListener('panel_mode_query', queryMode);
hostComponent.addEventListener('panel_mode_new', newMode);
}
private function editMode(evt:Event):void {
this.currentState = 'editing';
}
private function queryMode(evt:Event):void {
this.currentState = 'normal';
}
private function newMode(evt:Event):void {
this.currentState = 'adding';
}
答案 0 :(得分:2)
首先,你应该永远监听parent
或以任何方式访问父级,除了逻辑检查(主要是检查父级是否存在)。在OOP语言中,您永远不想处理对象链;你总是想要解决它。这既是正确的方法,也是防止错误的良好练习。
现在,针对实际问题。皮肤不是它所适用的对象。它不是该对象的一部分。两者之间的关系非常松散。您无法直接从主机访问皮肤,但可以直接从皮肤访问主机。
您可以使用hostComponent
访问皮肤附加到的组件。现在,正如我上面所说,你不想做hostComponent.parent
。首先,在将对象添加到父对象之前附加皮肤(除非您之后在AS3中手动添加它,我怀疑您正在做什么并且无论如何都是个坏主意)。相反,你想这样做:
fx:definitions
数组中的MXML以及皮肤中的MXML非常轻松地完成,您可以在MXML(使用{hostComponent.bindableVariableName}
)中监听更改,也可以通过监听PropertyChangeEvent.PROPERTY_CHANGE
事件来监听hostComponent。与皮肤交流是Flex的皇家痛苦。这是一种有意的设计,但有时需要它。在创建有效的应用程序时,正确的方法是必不可少的。