我是flex和actionscript的新手。我正在尝试创建一个具有多个状态的小型flex应用程序,但是如果我有嵌套容器,看起来有些对象在我预期的时候没有被初始化,即使我将creationPolicy设置为“all” 。“
我已将问题简化为一个小例子,其中一个注释块显示 的工作时间。
使用现有代码,我收到此错误:“TypeError:错误#1009:无法访问main / init()处的空对象引用的属性或方法”,并且未安装事件处理程序。
如果我改为使用已删除Panel和VBox元素的注释块, 就可以了。
我知道我可以在mxml元素中添加一个click属性,但这只是一个简化的例子,我更感兴趣的是知道为什么在应用加载时没有初始化对象。
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
applicationComplete="init();"
currentState="start">
<mx:Script>
private function mainButtonHandler(event:Event):void{
currentState = "start"
}
private function startButtonHandler(event:Event):void {
currentState = "main";
}
public function init():void{
mainButton.addEventListener(MouseEvent.CLICK, mainButtonHandler);
startButton.addEventListener(MouseEvent.CLICK, startButtonHandler);
}
</mx:Script>
<!-- this does not work -->
<mx:states>
<mx:State name="main">
<mx:AddChild creationPolicy="all">
<mx:Panel creationPolicy="all">
<mx:VBox creationPolicy="all">
<mx:Button id="mainButton" label="Change to Start State"/>
</mx:VBox>
</mx:Panel>
</mx:AddChild>
</mx:State>
<mx:State name="start">
<mx:AddChild creationPolicy="all">
<mx:Panel creationPolicy="all">
<mx:VBox creationPolicy="all">
<mx:Button id="startButton" label="Change to Main state"/>
</mx:VBox>
</mx:Panel>
</mx:AddChild>
</mx:State>
</mx:states>
<!-- this works -->
<!--
<mx:states>
<mx:State name="main">
<mx:AddChild creationPolicy="all">
<mx:Button id="mainButton" label="Change to Start State"/>
</mx:AddChild>
</mx:State>
<mx:State name="start">
<mx:AddChild creationPolicy="all">
<mx:Button id="startButton" label="Change to Main state"/>
</mx:AddChild>
</mx:State>
</mx:states>
-->
</mx:Application>
感谢您的反馈。
答案 0 :(得分:2)
如果你要做下一件事怎么办:
<mx:State name="main">
<mx:Panel creationPolicy="all">
<mx:VBox creationPolicy="all">
<mx:AddChild creationPolicy="all">
<mx:Button id="mainButton" label="Change to Start State"/>
</mx:AddChild>
</mx:VBox>
</mx:Panel>
</mx:State>
如果您不喜欢这样,请将Button切换到自定义组件基于Panel with VBox和Button,这样您就可以将其重写为几乎与注释代码相似,但您将使用容器。
如果我们回答问题为什么关于访问的奇怪内容会成真:
因为您使用了3个容器:Panel VBox和Button,并且在仅面板完成后完成了对应用程序/创建完成的事件 - 完成,而不是其子项。
清除?
答案 1 :(得分:0)
最诚挚的问候 尤金
答案 2 :(得分:0)
由于creationPolicy =“all”属性不像我想象的那样工作,因此对于复杂的状态更改,我为每个状态设置了一个“状态初始化”方法,键入了currentStateChange事件。这是我所做的一个例子,其中还包括使用Flex 4状态的更新,即使我在示例中没有使用spark组件。
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
applicationComplete="init();"
currentStateChange="stateChange(event);"
creationPolicy="all"
currentState="bar"
>
<fx:Script>
import mx.controls.Alert;
import mx.events.StateChangeEvent;
private var InittedStates:Object = new Object();
private function mainButtonHandler(event:Event):void{
currentState = "bar"
}
private function startButtonHandler(event:Event):void {
currentState = "foo";
}
public function stateChange(event:StateChangeEvent):void{
if (event.newState === 'bar'){
initBarState();
}
else if(event.newState === 'foo'){
initFooState();
}
}
public function initBarState():void {
if (InittedStates.bar){
return;
}
startButton.addEventListener(MouseEvent.CLICK, startButtonHandler);
InittedStates.bar = true;
}
public function initFooState():void {
if (InittedStates.foo){
return;
}
mainButton.addEventListener(MouseEvent.CLICK, mainButtonHandler);
InittedStates.foo = true;
}
public function init():void{
}
</fx:Script>
<s:states>
<s:State name="foo"/>
<s:State name="bar"/>
</s:states>
<mx:Panel includeIn="foo" creationPolicy="all">
<mx:VBox creationPolicy="all">
<mx:Button id="mainButton" label="Change to Start State"/>
</mx:VBox>
</mx:Panel>
<mx:Panel includeIn="bar" creationPolicy="all">
<mx:VBox creationPolicy="all">
<mx:Button id="startButton" label="Change to Main state"/>
</mx:VBox>
</mx:Panel>
</s:Application>