Flex AS3:ProgressBar不会移动 [英] Flex AS3: ProgressBar doesn't move

查看:117
本文介绍了Flex AS3:ProgressBar不会移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点困惑,需要一些建议/帮助.

I am a little stuck and need some advice/help.

我有一个进度条:

<mx:ProgressBar id="appProgress" mode="manual" width="300" label="{appProgressMsg}" minimum="0" maximum="100"/>

我有两个侦听器功能,一个设置进度,另一个设置appProgressMsg:

I have two listener functions, one sets the progress, and one sets the appProgressMsg:

public function incProgress(e:TEvent):void {
    var p:uint = Math.floor(e.data.number / e.data.total * 100);
    trace("Setting Perc." + p);
    appProgress.setProgress(p, 100);
}
public function setApplicationProgressStep(e:TEvent):void {
    trace("Setting step:" + e.data);
    appProgressMsg = e.data;
}

我想大量重复使用此进度条.不一定是ProgressEvents,而是在执行步骤时.

I want to reuse this progress bar alot. And not necessarily for ProgressEvents, but when going through steps.

例如,我遍历一堆数据库插入,并想取消进度等操作.

For instance, I loop over a bunch of database inserts, and want to undate the progress etc.

以下是示例:

public function updateDatabase(result:Object):void {
    var total:int = 0;
    var i:int = 0;
    var r:SQLResult;
    trace("updateDatabase called.");
    for each (var table:XML in this.queries.elements("table")) {
        var key:String = table.attribute("name");
        if (result[key]) {
            send(TEvent.UpdateApplicationProgressStep, "Updating " + key);
            i = 1;
            total = result[key].length;
            for each (var row:Object in result[key]) {
                //now, we need to see if we already have this record.
                send(TEvent.UpdateApplicationProgress, { number:i, total: total } );
                r = this.query("select * from " + key + " where server_id = '" + row.id + "'");
                if (r.data == null) {
                    //there is no entry with this id, make one.
                    this.query(table.insert, row);
                } else {
                    //it exists, so let's update.
                    this.update(key, row);
                }
                i++;
            }
        }

    }
}

一切正常.

也就是说,调用了侦听器函数,并且我得到了如下的跟踪输出:

That is, the listener functions are called and I get trace output like:

updateDatabase called.
Setting step:Updating project
Setting Perc 25
Setting Perc 50
Setting Perc 75
Setting Perc 100

问题是,仅显示了最后一个百分比和步骤.也就是说,完成所有操作后,进度条将跳至100%并显示最后一步标签.

The issue is, only the very last percent and step is shown. that is, when it's all done, the progress bar jumps to 100% and shows the last step label.

有人知道这是为什么吗?

Does anyone know why this is?

在此先感谢您的帮助, 杰森

Thanks in advance for any help, Jason

新的代码非常有用,我可能会添加:

The new code, which works awesomely I might add:

public function updateDatabase(result:Object, eindex:int = 0, sindex:int = 0 ):void {
    var total:int = 0;
    var i:int = 0;
    var j:int;
    var r:SQLResult;
    var table:XML;
    var key:String;
    var elems:XMLList = this.queries.elements("table");
    var startTime:int = getTimer();
    var row:Object;
    for (i = eindex; i < elems.length(); i++) {
        table = elems[i];
        key = table.attribute("name");
        if (!result[key])
            continue;
        total = result[key].length;
        send(TEvent.UpdateApplicationProgressStep, "Updating " + key);
        for (j = sindex; j < result[key].length; j++) {
            if (getTimer() - startTime > 100) {
                setTimeout(updateDatabase, 100, result, i, j);
                send(TEvent.UpdateApplicationProgress, { number:j, total: total } );
                return;
            }
            row = result[key][j];
            r = this.query("select * from " + key + " where server_id = '" + row.id + "'");
            if (r.data == null) {
                //there is no entry with this id, make one.
                this.query(table.insert, row,false);
            } else {
                //it exists, so let's update.
                this.update(key, row,false);
            }
        }
        send(TEvent.UpdateApplicationProgress, { number:1, total: 1 } );
    }
}

推荐答案

Flash是单线程的.在函数返回之前,显示不会更新.因此,您的任何代码都不应运行超过约100毫秒(1/10秒)的时间,否则UI(甚至整个浏览器)将被锁定.

Flash is single threaded. The display will not update until your function returns. For this reason, you should never have any code that runs for longer than about 100ms (1/10th of a second), otherwise the UI (or even the entire browser) will appear to be locked up.

一般的解决方案是将您的工作分成多个帧,这是一些伪代码:

The general solution is to split up your work over multiple frames, here is some pseudo-code:

function doWork(arg1:Obj, arg2:Obj, start:int=0) {
   var startTime = getTimer(); // store starting time
   for(i=start; i<length; i++) {
     if(getTimer() - startTime > 100) { // see if we've been working too long
        trace("Current progress: "+(i/length * 100)+"%");
        updateProgress( i / length );
        setTimeout(doWork, 100, arg1, arg2, i); // schedule more work to be done
        return; // stop current loop
     }
     trace("Working on item "+i);
     // processing here
   }
   trace("All work done");
}

doWork(data1, data2); // start the work

这篇关于Flex AS3:ProgressBar不会移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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