tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/723-how-to-use-form-after-it-is-fully-added-to-stageRobotlegs: Discussion 2012-01-05T13:04:50Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-21T11:01:07Z2011-11-21T11:01:07ZHow to use form, after it is "fully" added to stage?<div><p>Hi there,</p>
<p>if this form extends UIComponent, and dispatches
creationComplete, then Robotlegs waits for this event before the
Mediator runs onRegister.</p>
<p>What kind of actions are you performing? Are they related to
data, or more like skinning?</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-21T11:21:58Z2011-11-21T11:23:15ZHow to use form, after it is "fully" added to stage?<div><p>I'm copying or moving desktop files and I want to show progress
on the next form, but form occurs too late - it shows in the half
of the process or after it ends.</p>
<p>And yes, it's uicomponent (spark.components.form).</p></div>maciekreitag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-21T14:24:49Z2011-11-21T14:31:24ZHow to use form, after it is "fully" added to stage?<div><p>Hi,</p>
<p>Help us understand your issue by answering a few questions
:)</p>
<ol>
<li>
<p>In an AIR application you have 2 Views: I’ll call them
FileManagerView and ProgressIndicatorView. (I can’t come up
with better names right now)<br>
Inside your FileManagerView you are performing actions like
File.copyTo(),File.moveTo()or maybe you are using a FileStream
object to read and write files.<br>
Your ProgressIndicatorView is supposed to visualize the progress of
the tasks occuring in FileManagerView<br>
Right?</p>
</li>
<li>
<p>How is the not functioning View(ProgressIndicatorView) added to
the display list? Are you using states? Are you using a ViewStack?
Are you adding it through actionscript?</p>
</li>
<li>When are you adding the View to the display list? Before or
after the FileMangerView has been added to the display list?</li>
<li>Are you disptching an event from the FileMangerView, that its
mediator would re-dispatch and the ProgressIndicatorView’s
mediator would listen to it?</li>
<li>Are the FileStream operations synchronous or asynchronous?</li>
</ol>
<p>So, in case I missed the point completely more details about
your specific use case are needed in order to find the culprit
:)</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-21T17:20:13Z2011-11-21T17:23:22ZHow to use form, after it is "fully" added to stage?<div><ol>
<li>
<p>It works this way:<br>
1.1. I have MainView, in which I change curent visible form (lets
use your namspace, FileManagerView and ProgressIndicatorView). 1.2
In FileManagerView I gather information, like path were the files
have to be copied etc. 1.3. Then I click next button, which
dispatches event. MainView mediator handles this event and
FileManagerView is removed and ProgressIndicatorView is added as a
child of MainView. 1.4 Then I dispatch an event, which is handled
by command. This command executes service, that is responsible for
movying and copying files. 1.5 First part of file operations are
synchronous, but most of them are asynchronous. 1.6 When single
file is copied or moved, service dispatches event, that is handled
by ProgrssIndicatorView mediator. Mediator updates its views data,
showed by views progress bar (simple progess of copied files).</p>
</li>
<li>
<p>When I click next button and wait for ProgressIndicatorView to
occur, button freezes instead with FileManagerView still on board.
Then ProgressIndicatorView shows, but most of the process on the
progress bar is over or it is completly finished.</p>
</li>
</ol>
<p>I guess, I answered points 3, 4 and 5 in points 1.3-1.5.</p>
<p>As I think now, my problem can be those synchronous operations,
that freeze whole thing. Although, I need to create some files
before another and making this with chain-events, which wait one
for another like 6 times would too messy.</p>
<p>All in all, I hope, I clarified my sytuation, if not, I can
still answer more questions. I just whant to find a nice, clear way
to get rid of that ugly timer :)</p></div>maciekreitag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-21T18:26:51Z2011-11-21T18:26:51ZHow to use form, after it is "fully" added to stage?<div><p>ok. next round of questions:)</p>
<p>“Then I click next button, which dispatches event.
MainView mediator handles this event and FileManagerView is removed
and ProgressIndicatorView is added as a child of
MainView.”<br>
“When I click next button and wait for ProgressIndicatorView
to occur, button freezes instead with FileManagerView still on
board. Then ProgressIndicatorView shows, but most of the process on
the progress bar is over or it is completly finished.“</p>
<p>If you comment out the mapping for ProgressIndicatorView so it
has no mediator, and let MainView add it as you described, is this
“freezing” still occurring?</p>
<p>“Then I dispatch and event, which is handled by command.
This command executes service, that is responsible for movying and
copying files.”</p>
<p>Who is dispatching the event that triggers the command?</p>
<p>Is ProgressIndicatorView already added to the display list by
the time the service dispatches an event?<br>
I suspect that’s the problem: race condition. You are
probably dispatching an event with the name of the file as a
payload from FileManagerView’s Mediator to trigger the
command and make the service call. The service starts doing its
job, dispatches an event, none hears it, then MainView’s
mediator receives the event from NextButton and adds the
ProgressIndicatorView to the display list. At some point in time
ProgressIndicatorView’s Mediator is able to listen to the
events dispatched by the service and passes the data to the view
from this moment on, therefore incomplete.</p>
<p>One solution to this issue could be:</p>
<p>FileManagerView’s Mediator dispatches an event with the
file name as payload. The event triggers a command that sets the
filename in a FileManagerModel.<br>
When the user clicks the NextButton the MainView’s Mediator
adds ProgressIndicatorView to the stage. The
ProgressIndicatorView’s mediator onRegister() registers an
event listener for the event that will be dispatched by the service
and then dispatches an event to trigger a command that will first
read the filename set in FileManagerModel and call the service with
it as an argument.</p>
<p>Now, there is another solution as well, but I’m not sure
you want it. You’d have a FileManagerView containing the Form
<strong>and</strong> the ProgressIndicatorView, which will be
hidden at first. Nevertheless its mediator will be created and will
be able to listen to the event dispatched by the service. The user
fills in the file name, clicks next, FileManagerView’s
mediator dispatches the event with the filename as payload,
triggers the command, calls the service. The service dispatches an
event and ProgressIndicatorView’s Mediator in its
onDataReceived() method sets the ProgressIndicatorView to visible
and passes the data to the progressbar.</p>
<p>I wrote this down in a hurry, so I’m not sure if
it’s clear enough.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-21T18:48:40Z2011-11-21T18:49:55ZHow to use form, after it is "fully" added to stage?<div><p>If the way you’re adding the ProgressIndicatorView to the
display list isn't an issue and there are no race conditions, then
you should also look at discussions about commands detain() and
release() on this forum.<br>
Search for detain(), chaining commands.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-23T09:11:35Z2011-11-23T09:14:59ZHow to use form, after it is "fully" added to stage?<div><ol>
<li>"If you comment out the mapping for ProgressIndicatorView so it
has no mediator, and let MainView add it as you described, is this
“freezing” still occurring?"</li>
</ol>
<p>No, form appears as it should.</p>
<ol>
<li>"Who is dispatching the event that triggers the command?"</li>
</ol>
<p>ProgressIndicatorView mediator dispatches it (currently 50ms
after registered)</p>
<ol>
<li>"Is ProgressIndicatorView already added to the display list by
the time the service dispatches an event?"</li>
</ol>
<p>I guess, the mediators onRegister function triggers after child
is added to stage, so I'ld say yes.</p>
<ol>
<li>"I suspect that’s the problem: race condition. You are
probably dispatching an event with the name of the file as a
payload from FileManagerView’s Mediator to trigger the
command and make the service call. The service starts doing its
job, dispatches an event, none hears it, then MainView’s
mediator receives the event from NextButton and adds the
ProgressIndicatorView to the display list. At some point in time
ProgressIndicatorView’s Mediator is able to listen to the
events dispatched by the service and passes the data to the view
from this moment on, therefore incomplete.</li>
</ol>
<p>One solution to this issue could be:</p>
<p>FileManagerView’s Mediator dispatches an event with the
file name as payload. The event triggers a command that sets the
filename in a FileManagerModel.<br>
When the user clicks the NextButton the MainView’s Mediator
adds ProgressIndicatorView to the stage. The
ProgressIndicatorView’s mediator onRegister() registers an
event listener for the event that will be dispatched by the service
and then dispatches an event to trigger a command that will first
read the filename set in FileManagerModel and call the service with
it as an argument."</p>
<p>I'm not sure if this is race condition. If I state correctly in
previous answer, the onRegister function in
ProgressIndicatorViewMediator is triggered after
ProgressIndicatorView is added to stage. So theoretically form
should be added first and then command should be executed.</p>
<ol>
<li>"Now, there is another solution as well, but I’m not sure
you want it. You’d have a FileManagerView containing the Form
and the ProgressIndicatorView, which will be hidden at first.
Nevertheless its mediator will be created and will be able to
listen to the event dispatched by the service. The user fills in
the file name, clicks next, FileManagerView’s mediator
dispatches the event with the filename as payload, triggers the
command, calls the service. The service dispatches an event and
ProgressIndicatorView’s Mediator in its onDataReceived()
method sets the ProgressIndicatorView to visible and passes the
data to the progressbar."</li>
</ol>
<p>I guess, I havent described how my whole app works. I have
MainView and 6 forms in it, which are switched one after another by
Next or Back button. I have also model, which stores data from
those views.</p>
<p>When form dispatches some button events, which handled by its
mediator, changes some local data (e.g. browse action), then model
is automatically updated. If form has some textfields, there are
saved in model after next or back click occurs and form is changed
to next one (I could add onChange handler to every one, by it
seemed too hard working).</p>
<p>The case is, when FileManagerView to ProgressIndicatorView, I
dont have to dispatch event that changes file location data,
because its already stored in model.</p>
<p>About view in view solution, well sounds like it could work, but
I fear about changing whole thing so drastically. I already have
Views in View. Although, if there will be no solution, I could try
it.</p>
<ol>
<li>"If the way you’re adding the ProgressIndicatorView to
the display list isn't an issue and there are no race conditions,
then you should also look at discussions about commands detain()
and release() on this forum.<br>
Search for detain(), chaining commands."</li>
</ol>
<p>Hm... but even, if command would be already initiated, I still
dont know how to dispatch event from ProgressIndicatorView
mediator, after its view would be fully added and showed on
stage.</p>
<p>(EDIT. Why I have all "1"s in numeric list, although I used 1-7?
O_o)</p></div>maciekreitag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-23T09:48:05Z2011-11-23T09:48:05ZHow to use form, after it is "fully" added to stage?<div><p>I’m willing to take a look at your code, if you’d
let me see it (strip out your proprietary code and post an FXP or
zip of the project ??)<br>
It’s quite difficult to understand what’s going on
without seeing some code:<br>
at least a simplified version of the MainView, FileManagerView,
ProgressIndicatorView and their Mediators<br>
What do you think?</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-23T10:36:44Z2011-11-23T10:36:44ZHow to use form, after it is "fully" added to stage?<div><p>Ok, I have compressed app to needed files. FileManagerView is
GenerateFormView, then you have GeneratePopupView, which checks if
everything is clear, and then is launched ProgressIndicatorView as
ProgressFormView (in my case).</p></div>maciekreitag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-23T10:40:22Z2011-11-23T10:40:22ZHow to use form, after it is "fully" added to stage?<div><p>ok. I'll take a look at it and answer as soon as possible:)</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-23T15:07:44Z2011-11-23T15:07:44ZHow to use form, after it is "fully" added to stage?<div><p>Wow! It wasn’t easy to understand your code;) Since
it’s incomplete and a lot of classes are missing I
couldn’t compile it until I commented out a lot of code. From
what I could make work I saw this flow:</p>
<ol>
<li>GenerateFormView dispatches GenerateFormView.BROWSE_CLICK</li>
<li>GenerateFormViewMediator dispatches
BrowseDestinationEvent.BROWSE</li>
<li>BrowseDesinationCommand ->
LoadDestinationFolderService.browse()</li>
<li>LoadDestinationFolderService.handleSelect ->
BrowseDestinationEvent.BROWSE_RESPONSE</li>
<li>GenerateFormViewMediator. handleBrowseResponse ->
view.setBrowseInput(e.file.url);</li>
</ol>
<p>Then:<br>
1. MainMediator.handleNextClick dispatches
ChangedMenuEvent.CHANGED<br>
2. MainMediator.handleMenuChanged -> view.changeFormView->
this.MenuForm.addElement(formViews[formNumber]);<br>
3. ProgressFormView is added to the display list<br>
4. ProgressFormViewMediator.onRegister:<br>
addContextListener(GenerateApplicationEvent.GENERATE_APP_RESULT,
handleGenerationResult);<br>
addContextListener(ProgressGenerationEvent.GENERATION_PROGRESS,
handleProgress);<br>
dispatch( new
GenerateApplicationEvent(GenerateApplicationEvent.GENERATE_APP)
);<br>
5. triggers GenerateApplicationCommand -> calls
ApplicationGeneratorService.generate()<br>
6. and in setCurrentProgress dispatch( new
ProgressGenerationEvent(ProgressGenerationEvent.GENERATION_PROGRESS,
_currentProgress / progressTotal, label));<br>
7. ProgressFormViewMediator. handleProgress<br>
8. view.changeProgress(e.progress, e.label);</p>
<p>Now, to make it work I added GenerateFormView to MainView
through mxml.<br>
Then on next button click I did this:<br>
public function changeFormView(formNumber:int,
formViews:Array):void<br>
{ this.MenuForm.addElement(new ProgressFormView());</p>
<p>I couldn’t use the views from your model, because they
weren’t there.</p>
<p>In ApplicationGeneratorService I used a ‘for’ loop
to setCurrentProgress, which then dispatched the
ProgressGenerationEvent.GENERATION_PROGRESS.<br>
ProgressFormView is receiving the fake data from service!</p>
<p>Then I created another View and used your FormViewModel array
and Main.changeFormView to add and remove views and it also
worked.</p>
<p>There is no need to use the Timer in the
ProgressFormViewMediator’s onregister()</p>
<p>I suggest you isolate the ProgressFormView,
ProgressFormViewMediator, GenerateApplicationCommand and the
ApplicationGeneratorService by making a separate project containing
just them. If it doesn’t work as expected then I guess the
<strong>ApplicationGeneratorService</strong> is the problem. If i
could use your code I would try <strong>detain() and
release()</strong> in the command to see if it solved the
problem.</p>
<p>You could also try to use the logic from your
ApplicationGeneratorService in a simple ui component, i.e. without
the entire framework, and set the progressGeneration.setProgress in
the view and see if it works as expected.<br>
Another mini project could test the removing and adding of views in
Main.mxml. Use traces to see what happens with the Mediators’
onRegister for all your views.</p>
<p>I’m sorry for not being able to give you a better answer,
but I can’t use the ApplicationGeneratorService to see how it
works, because of the missing classes.</p>
<p>Something I’ve noticed while looking at your code: You
have BrowseDesinationCommand twice, under service and under
commands! I’m surprised you don’t get any errors
because of that. Maybe the command landed under the service folder
when you prepared the project for me.<br>
There are other things that I’ve noticed about your code and
package structure as well, but let’s concentrate on the
ProgressFormView first:)</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-23T18:17:57Z2011-11-23T18:17:57ZHow to use form, after it is "fully" added to stage?<div><p>I tried to use (partially) the logic from your
ApplicationGeneratorService. launchFile():<br>
I created some files, then I launched an AIR app (that I had on my
desktop), and it worked fine.<br>
Of course, as long as the launched AIR app was open the progress
bar didn’t move any further. The moment I closed the app, I
considered that the service has finished its job and I let it
dispatch<br>
(GenerateApplicationEvent.GENERATE_APP_RESULT,
"Success!\n\nApplication created."));</p>
<p>Now, you are making lots of calls in your
ApplicationGeneratorService.launchFile() in a sequential manner
(creating, copying files, launching a native app)...and I
can’t understand exactly what’s happening there. I
suggest commenting out all the calls and then checking every call
you make in your launchFile() step by step to see if there is one
causing some trouble. Maybe you should rethink the logic in this
launchFile() method?</p>
<p>But, if after testing everything works fine in your
ApplicationGeneratorService, then something else in your
application must be the cause of errors. I have no idea what it
could be. Since I was able to make it work (partially), it is clear
that you have to isolate the different areas of functionality in
your project and test them separately, at least by using the
debugger or trace statements.</p>
<p>Let us know how it goes.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-11-29T10:04:09Z2011-11-29T10:04:09ZHow to use form, after it is "fully" added to stage?<div><p>I would like to hear whether you’ve found a solution to
your problem or not. What was actually causing it?<br>
In case you still don’t know how to solve it and my
suggestions didn’t help, there may be others here who could
give you advice. Don’t hesitate to ask more questions :)</p>
<p>On the other hand, if you’ve resolved the issue and you
are willing to talk about it, it could help others with similar
problems. The purpose of this forum is to learn from each other (a
shared knowledge base)<br>
Cheers,<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-12-02T11:36:07Z2011-12-02T11:36:07ZHow to use form, after it is "fully" added to stage?<div><p>I'm sorry, that I made you wait so long for ma answer, but had
pretty hard deadlines during this time.</p>
<p>As I think about it now, Im also sorry for giving you just this
bunch of classes. I havent got permission to give you whole code,
because its app for company in which I work. Although, during
compression of code, I've forgot that besides giving you classes,
that have something to with the problem, they should also work
after separation... Thanks, that you where so patient and made it
work despite all problems.</p>
<p>The cause of my "freeze" problem was nothing more, but my
"createFile" functions in AppGenerationService class. If I use only
asynchronous methods, everything works fine. So I reduced using
synchronous functions to minimum (cause I still need some of them
badly) and even if app freezes, its too short period of time, to be
meaningful.</p>
<p>Although, this is just some backdoor, I've still havent solved
the problem fully. I thought about "detain() and release()"
methods, but I still need to somehow trigger/release command a
small moment after onRegister function executes in
ProgressViewMediator...</p></div>maciekreitag:robotlegs.tenderapp.com,2009-10-18:Comment/115641462011-12-02T14:44:21Z2011-12-02T14:44:21ZHow to use form, after it is "fully" added to stage?<div><p>Hey Maciej,</p>
<p>“I'm sorry, that I made you wait so long for ma answer,
but had pretty hard deadlines during this time.”</p>
<p>No problem:)</p>
<p>‘As I think about it now, Im also sorry for giving you
just this bunch of classes. I havent got permission to give you
whole code, because its app for company in which I work.’</p>
<p>That’s understandable. I'm sorry I couldn't be of more
help.</p>
<p>’The cause of my "freeze" problem was nothing more, but my
"createFile" functions in AppGenerationService class.’</p>
<p>I wish you luck in finding a better solution :) You still can
refactor this part of your application at a later time.</p>
<p>I'm going to close this thread, but feel free to reopen it if
need be.</p>
<p>Cheers,<br>
Ondina</p></div>Ondina D.F.