有没有办法临时将Flex的主应用程序交换到另一个应用程序然后切换回来。 场景:主应用程序启动,显示登录框 - 然后继续使用主应用程序。登录框也是一个应用程序。
Application.application是一个只读属性,尝试失败。
答案 0 :(得分:2)
我在模块化应用程序方面取得了巨大成功,主应用程序基本上由一个模块加载器组成,最初加载一个登录模块。
一旦登录模块完成了它的东西(在我的情况下验证了输入,称为登录服务并检索了一个令牌),它就会调度一个包含主应用程序所需细节的事件(富有想象力地称为“LogonEvent”)。我应该指出,登录模块本身只是执行所有实际工作的登录组件的包装器(因此登录组件可以在模块或ViewStack等中使用)。拥有一个LogonEvent会有所不同。
包装器应用程序通过卸载登录模块,加载包含应用程序内容的主模块,然后在加载的模块上设置所需的登录详细信息来处理登录事件。
注销按钮位于包装器应用程序中,以便它可以卸载主模块并重新加载登录模块,以便再次登录。
这种布局的好处是相对较小的登录模块加载速度非常快。当用户登录时,主模块已经预先加载,因此登录后通常无需等待主模块加载。如果你有一个大的单片应用程序,初始加载时间可能会偏离。
可能有帮助的一些代码...
private var mainModuleLogOnEventDispatcher:*;
[Bindable]
private var _logOnDetails:LogOnDetails = new LogOnDetails();
private function onCreationComplete(event:Event):void
{
// Load log on module.
loadMainModule("LogOnModule.swf");
// Pre-load main module while user is logging on.
var mm:IModuleInfo = ModuleManager.getModule("MainModule.swf");
mm.load();
}
[Bindable]
private function set logOnDetails(value:LogOnDetails):void
{
_logOnDetails = value;
}
private function get logOnDetails():LogOnDetails
{
return _logOnDetails;
}
private function loadMainModule(moduleName:String):void
{
// Unload anything already loaded.
if (mainModule.url.length > 0)
{
mainModule.unloadModule();
mainModule.url = "";
}
mainModule.addEventListener(ModuleEvent.READY, handleMainModuleReadyEvent);
mainModule.url = moduleName;
}
private function handleMainModuleReadyEvent(event:ModuleEvent):void
{
// Remove listener, we've caught the event now.
mainModule.removeEventListener(ModuleEvent.READY, handleMainModuleReadyEvent);
// Add listeners to other events or apply data.
if (mainModule.url == "LogOnModule.swf")
{
mainModuleLogOnEventDispatcher = mainModule.child;
if (mainModule.child != null) {
mainModuleLogOnEventDispatcher.addEventListener("logOnEvent", handleLogOnEvent);
}
}
if (mainModule.url == "MainModule.swf")
{
var mm:* = mainModule.child;
if (mainModule.child != null)
{
mm.logOnDetails = logOnDetails;
}
}
}
private function handleLogOnEvent(logOnEvent:LogOnEvent):void
{
mainModuleLogOnEventDispatcher.removeEventListener("logOnEvent", handleLogOnEvent);
logOnDetails = logOnEvent.logOnDetails;
// Now get person's details and swap in main module if successful.
var parameters:Object = new Object();
parameters.cmd = "viewPerson";
parameters.token = logOnDetails.logOnToken;
viewPersonRequest.send(parameters);
}
private function handleViewPersonRequestResult(event:ResultEvent):void
{
//*** Loads of setting logonDetails and error handling removed!!! ***//
loadMainModule("MainModule.swf");
currentState = "LoggedOn";
return;
}
private function onLogOff(event:MouseEvent):void
{
// Make sure we don't auto-logon when we log off.
var logOnPrefs:SharedObject = SharedObject.getLocal("LogOn", "/");
logOnPrefs.data.loggedOff = true;
var parameters:Object = new Object();
parameters.cmd = "logoff";
parameters.token = logOnDetails.logOnToken;
logoffRequest.send(parameters);
loadMainModule("LogOnModule.swf");
currentState = "";
}
<!-- *** Loads of view state related mxml removed *** -->
<mx:VBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" id="mainModuleVBox">
<basic:IJModuleLoader id="mainModule" url="" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle"/>
</mx:VBox>
我还应该注意,这个包装器应用程序实际上并不是一个应用程序!这实际上是一个模块本身,由Flex或AIR应用程序加载。这样我可以拥有单独的Flex和AIR项目,这些项目引用一个核心库项目,该项目包含应用程序模块,登录模块,主(后登录)模块以及应用程序使用的基本上所有其他组件和类。
答案 1 :(得分:1)
您是否有理由不能将登录框设为组件,然后使用ViewStack来控制可视组件?
答案 2 :(得分:0)
这很有趣,这正是我试图找出目前最好的方法。我曾想过使用ViewStack,但由于我已经使用了很多其他嵌套的ViewStack,我也在查看State标签。如果有人知道“正确的事”,我也会非常感兴趣!
答案 3 :(得分:0)
我已经在Application组件上将其实现为ViewStack;似乎工作正常。使用ViewStack上的selectedIndex或selectedChild属性来控制是否显示登录或应用程序UI。
<mx:Application>
<mx:ViewStack>
<mx:Box> <!-- or whatever for login-->
</mx:Box>
<mx:Box> <!-- application UI widgets here -->
</mx:Box>
</mx:ViewStack>
</mx:Application>