代码之家  ›  专栏  ›  技术社区  ›  J. Martin

flex as3:进度条不移动

  •  0
  • J. Martin  · 技术社区  · 14 年前

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

    我有一个进度条:

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

    我有两个侦听器函数,一个用于设置进度,另一个用于设置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;
    }
    

    我想重新使用这个进度条。不一定是进展事件,但在经历步骤时。

    例如,我循环了一系列数据库插入,并希望不注明进度等。

    这是一个示例:

    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++;
                }
            }
    
        }
    }
    

    一切正常。

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

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

    问题是,只显示最后的百分比和步骤。也就是说,完成后,进度条将跳到100%,并显示最后一步标签。

    有人知道这是为什么吗?

    事先感谢您的帮助, 杰森

    新的代码,我可能会加上:

    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 } );
        }
    }
    
    2 回复  |  直到 12 年前
        1
  •  2
  •   davr    14 年前

    闪光灯是单线程的。直到函数返回,显示屏才会更新。由于这个原因,您不应该有任何运行时间超过100毫秒(1/10秒)的代码,否则UI(甚至整个浏览器)将显示为锁定状态。

    一般的解决方案是将工作拆分为多个帧,下面是一些伪代码:

    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
    
        2
  •  1
  •   sra Jon    13 年前

    您的伪代码适用于更新进度条,但在我的情况下,我的“工作”是将文件从DVD复制到AppStorageDirectory,这似乎重新引入了您解决的问题-进度条现在不更新

    这是我对你的解决方案的理解

    function doWork(arg1:int, arg2:int, start:int=0) {
        var startTime = getTimer(); // store starting time
        for(var i:int=start; i<arg2; i++) {
            if(getTimer() - startTime > 100 ) { // see if we've been working too long
              trace("Current progress: "+(i/arg2 * 100)+"%");
              setTimeout(doWork, 100, i, arg2, i); // schedule more work to be done
              return; // stop current loop
          }
          trace("Working on item "+i);
          dispatchEvent(new progressMadeEvent("incrementChange",i,arg2))
          var dir:String = copyRes[i].nativePath.toString().split(OSSep).pop()
        copyRes[i].copyTo(appStore.resolvePath(dir)) // copies dir from DVD to appStorageDir
        }
        trace("All work done");
    }