使用 Flex ViewStack 重新创建/重置视图

Posted

技术标签:

【中文标题】使用 Flex ViewStack 重新创建/重置视图【英文标题】:Recreating/resetting views with Flex ViewStack 【发布时间】:2010-10-09 03:06:02 【问题描述】:

我正在为不同的应用程序状态编写一个使用 ViewStack 的 Adob​​e AIR 应用程序。有没有办法确保每个视图组件在每次显示/隐藏时都被创建/销毁?

例如,如果我在视图中有一个 TextInput,我希望它在每次切换到该视图时重置为初始状态,而不是之前输入的文本。或者,如果我有一个计时器,我希望它在我离开视图时被销毁,这样当我在应用程序的不相关部分时它就不会继续运行。我知道我可以手动初始化/销毁 show() 和 hide() 事件中的所有内容,但有更简单的方法吗?

【问题讨论】:

【参考方案1】:

AFAIK 没有内置的方法来执行此操作,因此您必须手动处理您提到的显示和隐藏事件。

ViewStack 确实有两种方法“saveState”和“loadState”也许可以帮助您解决这个问题。历史管理器使用这些方法来启用后退/前进导航。不过,文档似乎没有任何示例。

【讨论】:

【参考方案2】:

在创建/删除策略和管理状态方面,ViewStacks 可能是魔鬼的工作。我们在开发法定 ecoDrive 时遇到了各种各样的问题,大约 3/4 的时候我们都非常反对 ViewStacks 来管理我们应用程序中的视图状态。

但是... 一个不错的选择是首先将 creationPolicy 设置为 ContainerCreationPolicy.NONE。这样,您可以控制何时在 ViewStack 中创建任何面板。然后我认为您需要某种逻辑,以便当 ViewStack 更改面板时,它会删除或重置您所在的面板。

另一个可行的替代方法是使用视图状态。有一个作为主容器的基本状态,然后是每个部分的简单状态。这样,当您切换到新状态时,旧状态会以与其创建方式相反的顺序被删除。你必须对状态进行自律,因为当它们开始嵌套时,它们最终会变得非常复杂和混乱。如果您保持简单,它可能会按您的需要工作。

【讨论】:

【参考方案3】:

两个答案都是正确的——似乎没有任何内置的方法可以做到这一点。我通过为我的视图组件创建一个“包装器”组件解决了这个问题。每次显示视图时,它都会创建一个新的视图组件。这并不理想,但很好地满足了我的要求,并且需要对我的应用程序结构进行少量更改。

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" show="init()" hide="cleanup()">
    <mx:Script>
        <![CDATA[
            private var myComponent:MyComponent;

            private function init():void
            
                myComponent = new MyComponent();
                componentContainer.addChild(myComponent);   
            

            private function cleanup():void
            
                componentContainer.removeAllChildren(); 
            
        ]]>
    </mx:Script>

    <mx:Canvas   id="componentContainer" />
</mx:Canvas>

【讨论】:

【参考方案4】:

将您的“视图”构建为单独的模块,然后使用 ViewStack 在它们之间切换。然后,您可以编写一个函数来在触发 ViewStack 的“更改”事件时销毁未使用的模块(根据 selectedChild 属性检查每个模块)。

【讨论】:

【参考方案5】:

我为我的不同观点使用不同的状态。在每次状态更改时,我都会添加和删除组件。

这会导致UIComponent 触发的addremove 事件,这使我可以在每次添加组件时对其进行初始化和清理。

这就是想法……

   <mx:states>
      <mx:State name="state1">
         <mx:AddChild>
            <mx:SomeUIComponent id="myComp" add="myComp.initialize()" remove="myComp.cleanup()"/>
         </mx:AddChild>
      </mx:State>
   </mx:states>

【讨论】:

【参考方案6】:

在 MXML 2009 中,您可以使用 itemDestructionPolicy="auto" 在使用后销毁组件。如果在具有两种状态(init、logged)的第一个视图组件中使用此属性,则可以销毁并重新初始化所有子视图组件。示例:

   <s:states>
    <s:State name="init" />
    <s:State name="logged" />
  </s:states>

  <s:SkinnableContainer id="skincon"   backgroundAlpha="0"
                        backgroundColor="#FFFFFF">
    <s:VGroup id="MainContainer"   paddingTop="0"
              paddingLeft="20" paddingRight="20" gap="0">
      <views:_HeaderView id="header" />
      <mx:ViewStack id="viewStack"  >
        <s:NavigatorContent includeIn="init" itemDestructionPolicy="auto">
          <s:layout>
            <s:VerticalLayout horizontalAlign="center" verticalAlign="middle" />
          </s:layout>
          <views:LoginView title="Login" id="loginView" />
        </s:NavigatorContent>
        <s:NavigatorContent includeIn="logged" itemDestructionPolicy="auto">
          <s:layout>
            <s:VerticalLayout horizontalAlign="center" verticalAlign="top" />
          </s:layout>
          <views:_CentralView id="userView" />
        </s:NavigatorContent>
      </mx:ViewStack>
      <views:_FooterView id="footer" />

    </s:VGroup>
  </s:SkinnableContainer>

【讨论】:

以上是关于使用 Flex ViewStack 重新创建/重置视图的主要内容,如果未能解决你的问题,请参考以下文章

如何使用按钮打开一个新组件,FLEX

Flex:确定一个组件是否显示了

egret:ViewStack 中的scroller滚动条的隐藏

EUI ViewStack实现选项卡组件 (封装了一个UI类)

如何创建不会在页面重新加载时重置的 JSP 变量

重新初始化组件