Flex:在构建选项卡的 UI 组件之前,如何在更改选项卡时调用标题窗口 [英] Flex: how to call titlewindow when changing tab, before tab's UI components are built

查看:25
本文介绍了Flex:在构建选项卡的 UI 组件之前,如何在更改选项卡时调用标题窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Flex4 应用使用如下标签栏:

My Flex4 app uses a tab bar as follows:

<s:TabBar id="tabs"/>
    <mx:ViewStack id="vs" height="100%" width="100%">
        <s:NavigatorContent label="Tab 1"  width="100%" height="100%">
            ...
        </s:NavigatorContent>
        <s:NavigatorContent label="Tab 2"  width="100%" height="100%">
            ...
        </s:NavigatorContent>
        <s:NavigatorContent label="Tab 3"  width="100%" height="100%">
            ...
        </s:NavigatorContent>
    </mx:ViewStack>
</s:TabBar>

默认情况下,应用打开时使用 Tab 1.选项卡 2 尚未构建.

The app opens with Tab 1 by default. Tab 2 is not built yet.

问题是,当我将选项卡更改为 Tab 2 时,Flex 需要很长时间来构建 Tab 2 UI 组件并显示选项卡内容.该应用程序在此过程中基本上会冻结.我需要向用户提供一些他/她需要等待几秒钟的指示.

The problem is, when I change tabs to Tab 2, Flex takes a very long time to build the Tab 2 UI components and display the tab contents. The app basically freezes during this process. I need to provide some indication to the user that he/she needs to wait several seconds.

我尝试过使用光标管理器来创建一个忙碌的鼠标图标.这不起作用(例如,仅当 Tab 2 完成构建时,光标才会更改).

I've tried using the Cursor Manager to create a busy mouse icon. This didn't work (e.g. the cursor only changes when Tab 2 completes building).

我想在选项卡构建时简单地显示一个标题窗口.但是,当我切换选项卡时,我不知道如何启动它,这样标题窗口就会出现在 Tab 2 构建之前和构建时.

I'd like to simply display a title window while the tab builds. But, I don't know how to launch it when I switch the tab, such that the title window appears before and while Tab 2 is building.

我知道 mx ViewStack 可以有一个 change="" 属性,但是当我使用它时,直到 Tab 2 完成加载时标题窗口才会出现.

I know that the mx ViewStack can have a change="" property, but when I use that the title window doesn't appear until Tab 2 completes loading.

我不确定如何在以下场景中实现 callLater() 函数.

I'm not sure how to implement a callLater() function in the below scenario.

谁能帮我弄清楚如何触发标题窗口,使其在 Tab 2 构建之前和构建时出现?

Can anyone help me figure out how to trigger the title window so that it appears before and while Tab 2 builds?

参考文献:

我们如何实施请稍等……"应用程序忙时屏幕处于 flex 状态

Flex: 寻找设计模式以在我的应用程序忙碌"时显示忙碌的光标

更新 1:

通过下面 David 的 createDeferredContent 评论和上面链接的上一篇文章中来自 weltraumpirat 的 setTimeout 评论,我能够一起破解一个解决方案,导致显示繁忙的光标而标签 2 中的内容加载.这是我所做的:

With the createDeferredContent comment from David below and setTimeout comment from weltraumpirat in my previous post linked above, I was able to hack together a solution resulting in a busy cursor displayed while the content in tab 2 loads. Here's what I did:

将选项卡 2 创建为实现以下内容的组件:

Create Tab 2 as a component implementing the following:

<s:VGroup 
    ...
    preinitialize="preinit"
    creationComplete="start1">

    private function preinit():void {
        mx.managers.CursorManager.setBusyCursor();
    }

    private function start1():void {
        setTimeout(start2,100);
    }

    private function start2():void {
        // create mxml components
        myBC.createDeferredContent();

        // place any required actionscript code here
        mx.managers.CursorManager.removeBusyCursor();
    }

    ...

    <s:BorderContainer id="myBC" creationPolicy="none">
        <!--- place all mxml code here to create layout -->
    </s:BorderContainer>

</s:VGroup>

一些注意事项:

(1) 虽然在 Tab 2 完成构建之前会显示忙光标,但应用程序仍然冻结,并且当用户移动鼠标时,忙光标会停留在屏幕上,而默认鼠标图标(箭头)会在屏幕上移动由用户控制,直到 Tab 2 完成构建并显示.不理想,但至少忙碌的光标表明应用程序正在做某事.如果我愿意,我可以用指示忙等的标题窗口替换忙光标.

(1) While a busy cursor does display before Tab 2 completes building, the app still freezes and when the user moves the mouse the busy cursor stays put on the screen while the default mouse icon (the arrow) moves around the screen as controlled by the user until Tab 2 completes building and gets displayed. Not ideal, but at least the busy cursor indicates the app is doing something. If I wanted to, I could replace the busy cursor with a titlewindow indicating busy, etc.

(2) 将超时时间从 100 ms 更改为 50 ms 仍然会产生良好的结果.但是将其减少到 10 ms 会导致仅在构建和显示所有组件时才会出现忙碌光标.预计将超时减少到某个阈值以下会导致这种行为.我想知道这个超时值的阈值(例如在 10 到 50 毫秒之间)是否取决于客户端计算机?或者,如果我使用 100 毫秒,这是否可以安全地覆盖所有客户端计算机?(我们怎么知道它会?)

(2) Changing the timeout from 100 ms to 50 ms still produces good results. But reducing it to 10 ms causes the busy cursor to appear only when all components are built and displayed. It's to be expected that reducing the timeout below some threshold will cause such behavior. I wonder if this threshold for timeout value (e.g. somewhere between 10 and 50 ms) depends on the client computer? Or, if I used 100 ms, does that safely cover all client machines? (How do we know it will?)

(3) 我本来希望用 callLater(start2); 替换 setTimeout(start2,100); 并删除 creationPolicy="none" 应该产生类似的结果,但它不会(例如,忙光标永远不会出现,应用程序冻结几秒钟,直到显示选项卡 2).我以前从未使用过 callLater(),所以也许我做错了什么(?).

(3) I would have expected that replacing setTimeout(start2,100); with callLater(start2); and deleting creationPolicy="none" should produce a similar result, but it doesn't (e.g. the busy cursor never appears and the app freezes for a few seconds until Tab 2 gets displayed). I've never used callLater() before, so maybe I did something wrong (?).

推荐答案

如果您在 Tab2 初始化期间有大量计算,您可以将它们分成小块并使用 callLater 机制连续执行.

In case you have heavy calculations during Tab2 initializaition you can split them by small chunks and execute them consecutively using callLater mechanism.

这是一个非常简单的例子:

Here is VERY simplified example:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
           xmlns:s="library://ns.adobe.com/flex/spark" 
           xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
    <![CDATA[
        import mx.core.FlexGlobals;
        import mx.events.FlexEvent;
        import mx.managers.CursorManager;

        private var i:int = 0;

        protected function nc2_initializeHandler(event:FlexEvent):void
        {
            FlexGlobals.topLevelApplication.enabled = false;                
            CursorManager.setBusyCursor();
            callLater(initTab2);
        }

        protected function initTab2():void
        {
            var j:int;

            //Part of calculations
            for (j=0; j< 10000; j++)
            {
                i++;
            }   

            //Check if completed
            if (i<1000000)
            {
                //If not call again
                callLater(initTab2);                    
            }
            else
            {
                //Finished
                CursorManager.removeBusyCursor();
                FlexGlobals.topLevelApplication.enabled = true;
            }
        }

    ]]>
</fx:Script>
<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:VGroup gap="10" top="10" left="10">
    <s:TabBar id="tabs"  dataProvider="{vs}"/>
    <mx:ViewStack id="vs" width="100%" >
        <s:NavigatorContent label="Tab 1"  width="100%" height="100%" >
            <s:Label text="Tab1 content"/>
        </s:NavigatorContent>
        <s:NavigatorContent id="nc2" label="Tab 2"  width="100%" height="100%">
            <s:Label text="Tab2 content" initialize="nc2_initializeHandler(event)"/>
        </s:NavigatorContent>
        <s:NavigatorContent label="Tab 3"  width="100%" height="100%">
            <s:Label text="Tab3 content"/>
        </s:NavigatorContent>
    </mx:ViewStack>

</s:VGroup>

这篇关于Flex:在构建选项卡的 UI 组件之前,如何在更改选项卡时调用标题窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆