2010-04-28 3 views
0

Я немного застрял и вам нужен совет/помощь.Flex AS3: ProgressBar не перемещается

У меня есть прогресс бар:

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

Я хочу повторно использовать этот прогресс бар много. И не обязательно для ProgressEvents, но при выполнении шагов.

Например, я петля над кучей вставок базы данных, и вы хотите undate прогресс и т.д.

Вот пример:

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

Я также пробовал это с помощью mx: Label, где я просто показываю процент, он ведет себя одинаково, несмотря на получение сообщения для обновления. Интерфейс также немного заморожен, поэтому я предполагаю, что он блокирует, но не уверен, как это сделать? –

ответ

2

флэш однопоточен. Дисплей не будет обновляться, пока ваша функция не вернется. По этой причине у вас никогда не должно быть кода, который работает дольше 100 мс (1/10 секунды), в противном случае пользовательский интерфейс (или даже весь браузер) будет заблокирован.

Общее решение разделить работу над несколькими кадрами, вот некоторые псевдо-код:

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 
+0

Чувак, вы просто править. –

1

Ваш псевдо-код работает для обновления индикатор выполнения, однако в моем случае моя «работа» была копирование файлов из 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"); 
} 
Смежные вопросы