Flex 3 - Force all controls to render at start - apache-flex

When I try to access the hidden TABs of my tab navigator control in action script, it returns a null error. But it works OK if I just activate the control in the user interface once. Obviously the control is not created until I use it. How do I make all the tabs automatically created by default ?

<mx:TabNavigator creationPolicy="all"/>
That should do it. Deferred instanciation is a feature, but sometimes it is a hassle.

The Flex framework is optimizing creation be default (creationPolicy="auto") so if you have a configuration dialog with a lot of tabs, for example, and the most useful tab is the first one, your application does not spend time and memory initializing the tabs that the user never sees.
This makes a lot of difference when dialogs like this never release, and is a good default to go with.
One thing to look at is using a private variable in your dialog/form instead of pushing the data to the control on the hidden page. This style treats the whole form as if it were a component, which it sort of is. To repeat: the MXML form/dialog/canvas is a class, and it can have data and methods in addition to containing other components.
Cheers

On a side note, I've run into the deferred-loading policy in a multi-state application, and circumvented it by forcing all elements to be included and invisible in the initial state. Something to consider, but only as a hack.

Related

Dynamically changing component arrangment in QML

What would be the preferred (recommended) way to rearrange the components of a QML UI on an event such as a button click?
I do have designed a UI consisting of a bunch of custom components, each of them is bound to a (C++) model. I use anchors to position the components in the ApplicationWindow.
On a button click, I want to add an additional component which, due to its size, makes it necessary to rearrange the existing components. Actually, the button could be understood as switching into a different mode such as the Debug view in an IDE (think of Eclipse).
My goal is to keep the components in a consistent state between views and make the switch as fluent as possible.
I could think of these options:
Design two different views, and use a Loader or State to switch between them. As initializing the models takes some time, they should remain not be deleted during switching. I think, setting them as ContextProperty of the QMLApplicationEngine should take care of that.
Do a lot of rearranging in the onClicked()-Handler of the button. Probably the worst solution but does not require to reinitialize the components and models.
I think the most elegant solution would be to initialize the components in a some kind of container (or model) and then assign different layouts to this container on button click. But I have no idea, if this is possible and how to achieve that.
Edit: I followed approach 1. by using the StackLayout. It works basically, but it seems as if the invisible UI is still running in the background and consuming resources (e.g. requesting Images from my QQuickImageProvider).
Using a Loader eliminates this problem as it destroys the previous UI on every change of the source property. What I do like about the StackLayout however is that it preloads all UIs on app startup. So the transitions are smoother compared to the Loader. Is there a way to disable the invisible UIs?
Your option (1) is the one giving your the most flexibility, since you have two entirely separate UIs depending on state.
As you already discovered yourself this requires keeping all relevant state data in a way that is accessible by both UIs, e.g. in C++ or in globally accessible QML/Script objects.
I would go for that if you envision any more changes or tweaks than just rearranging elements.
If you are sure that rearranging elements will be sufficient, have a look at QML states
It is a bit like a combination of your options (2) and (3).
The state setup allows you very locally to define anchors and other properties for each element depending on a named state.
The button's signal handler then only needs to change which of the states is active, by assigning one of the names to the respective state property.

Flex Spark List item render with delayed refresh

I have a spark List in which I am adding custom components manually (without an item renderer). Everything is working fine except when I add hundreds of items in the list (based on several calculations), the render time increases to several seconds.
My questions are:
Does flex automatically delay the rendition of components that are added to a list?
If not then, how can I tell the spark list to only render the components once everything is added.
I hope what I am asking makes sense. I am pretty sure the render time is increasing because I have quite a few components inside the custom component. I just need a simple answer to my questions.
One more thing to know is that,
ActionScript 3 runs on flash player based on even-driven. It means that if you run a chunk of code in blocking, anything else, including rendering, will not be executed until the code ends.
This design sometimes causes issues: If a developer adds too much job in one blocking function, the player looks frozen and unresponsive momentarily. (If the code is an infinite loop, it stops until the player detects and throws ScriptTimeoutError, or possibly forever.)
However, for your question, yes, anything will be delayed until the adding job is done. Flex components doesn't basically split the job automatically.
Flex components are rendered in the list according to the Flex lifecycle: http://help.adobe.com/en_US/flex/using/WS460ee381960520ad-2811830c121e9107ecb-7fff.html
There are two reasons your List may be running slow, your components may not be following the Flex lifecycle correctly and the second because virtual layouts are not enabled on your List.
First the hard one:
Your first step should be to ensure you are following the correct phases in your custom components for commitProperties(), measure() and updateDisplayList(unscaledWidth:Number, unscaledHeight:Number).
So long as you are not calling any method named validateNow() on either your UIComponent subclasses or the LayoutManager then your components should follow this just fine.
The second may be that your list layout is not using virtual layout. This is enabled by default in a Spark List component but if you're overriding the layout you should ensure that useVirtualLayout is set to true on whatever layout you're using.
This is the property to enable it:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/components/List.html#useVirtualLayout
This is what it does to speed up rendering many items in a Spark DataGroup component (which a List is):
http://help.adobe.com/en_US/flex/using/WSc2368ca491e3ff92-1483ec4a12136246e76-8000.html#WS685c4ccbb85d340c6617851e121d4b8abae-8000

Flex tabbed view gets reloaded every time

I have a very simple Flex application for mobile phones which uses 3 tabs (with the TabbedViewNavigatorApplication).
It seems that everytime I switch tabs, the selected view is reloaded.
I've set a creationComplete command to do something and everytime I click on the tab it executes the function.
Isn't it possible for the views to get loaded 1 time and that's it?
Seems to me that this behaviour is exactly the point on mobile devices since you want to keep memory / cpu usage as low as possible.
This effectively means destroying all non-active views and all related view components / objects.
However you can override this default behaviour by setting the destructionPolicy on every view to destructionPolicy="never".
This blog post will explain the basic understanding you will need to obtain.
Cheers

Flex Spark tabbar : initialize hidden tabs

problem is I have a spark Tabbar, with many forms in each tab.
But I have a single global save button. Problem is, if I don't open a Tab,
it doesn't get initialized and therefore the forms it contains do not exist..
How Can I make it as if the user had clicked on every tab?
The best way to handle this is to have a data model that each tab is displaying and editing, rather than trying to go in and read the values out of the controls in each tab, and save those. This is at the heart of MVC.
However, if you're too invested in your current architecture to be able to change it and you are using a ViewStack with your TabBar, you may find that setting creationPolicy to "all" does what you want. If you're using States, I don't think you can force all of them to be instantiated without putting your application into each State at least once.

Flex Cairngorm 3 Presentation Model Initializations

ok so I have a TitleWindow that I open up... and I have 6 states defined. I am using the Presentation model pattern for all of my views. I have discovered a frustrating nuance. When I tell my window to go to XXX state, the controls have to initialize since the states in flex use lazy loading. so... my PM code that says myTextArea.text bombs out and say "cannot access..." so as a work around, I made some creationComplete events on my controls to register the control with the PM. So when the state changes, the textarea finally initializes and on creationComplete calls PM.registerTextArea() which sets a reference to it. then in that function I run my code... myTextArea.text.. etc.
This seems like such a ugly hack that I hate it. Is there any way to wait until the entire state in created then call code on the PM? I have tried enterstate... but this event seems to fire before the state controls are ready.
I tried to add a comment, but I guess editing is the only way I can do this...
to everyone: thanks for the great feedback. I am doing something slightly off straight PM. Every view has a viewController (as I call them). Its kinda my own hybrid of a delegate / dataprovider. But this is moot. It's the flex component lifecycle when dealing with states that is the pain. if you change state.. there is no event to say "all my components in this state are ready". only event to say "we changed state". so my code that fires on state change is trying to talk to components that aren't ready yet. So from what I see, there seems to be no design pattern or perfect way to ensure that all components are created in a state unless using creationComplete on every component in the state to register it is ready... if you don't, you get a race condition. Regardless of frameworks or design patterns, this seems to be a root issue.
The textarea is an easy PM fix.. just bind it to the pm value. But there are other times I can't.
Specifically, I am trying to attach video to a display once I get to that state. This is done via addchild. regardless of where I do it.. I need to know that the videoDisplay is done loading before I call addchild. I even tried currentStateChange event since docs say that fires last... but alas.. the components in the state are still initializing. So it seems that creationComplete is my only option. Maybe the only sane way to keep to clean code is to create the entire thing (videodisplay and video) using as once the state is entered. I just hoped the flex framework had events to ehlp me here rather than buiilding everything on the fly in as.
Since your PM has a reference to a visual component (myTextArea), this isn't a completely pure form of a presentation model. It appears to be more of a supervising presenter / controller type of setup.
That being said, the way I would fix your problem would be to use a complete presenter outright ( no knowlege of the view at all ) or use a complete controller ( view implements an interface through which the controller communicates ). The advantage of using a presenter in Flex is that you can create a bindable value such as text or selectedItem, and the view will bind to that variable whenever it comes online so the issues dealing with the lifecycle of Flex components go away.

Resources