Use certain component depending of state in flex 3 - apache-flex

Depending of some flag I want to use certain component in my mxml.
There is not a default value. So it's probably incorrect to put one in mxml and then with states remove it and add the other.
Both also share the same interface, and I call methods in Actionscript using id. That means that if I put them in different states in mxml, the compiler will complain about same id used 2 times.
Is there any conditional statement or state management like: if x use this component, else use other one (preferably with mxml not actionscript) ? And in a way they are mutually exclusive (can have same id)?

Make ie. both components properties visible and includeInLayout listen (bound) to the flag. You can also use states. Always react on events that the components should dispatch. In the listener you can use the currentTarget to get the sending component.
The other way arround if you like to set a behaviour from somwhere without having access to the component id, define bindable properties and let both components listen to changes through bindings like I said with ie. the visible attribute.
This normaly should work for all requirements. If you can give me some sample code I could write you a short sample and moreover we could add it to your question.

Related

Angular 6, how to change style (rotate, colour, scale) of img based on variables (continuous change)

In Angular to change the styling of an element or component I understand there are tools available in the form of directives (ngStyle, ngClass). However as far as I can tell, ngClass allows for conditional styling only in which one changes styling based on a particular scenario. These are therefore changes based on discrete conditions.
ngStyle allows an object to be passed which can in theory do this by returning a style object which is custom defined, but then ngStyle is listening perpetually to page changes, whereas I wish to trigger the style change when a specific action occurs, instead of listening to all page changes if possible?
I would like to programmatically change an images's css properties programmatically (rotation, width, height, opacity) based on perhaps a button press, or a mouse event, or just when a function is called, but the key is I want those changes to be continuous, for example, a rotation based on a variable in the component class, no discrete options of class changes.
In Angular, how would this be done? ViewChild allows access to the DOM and therefore the styling, but the styles are read-only it would seem as they are computed.
I can't post code, as I don't know where to start to make such a thing work.
but then ngStyle is listening perpetually to page changes, whereas I wish to trigger the style change when a specific action occurs, instead of listening to all page changes if possible?
That's the whole point of Angular: you bind data to the view via a declarative template syntax it offers, and let it figure out when to update.
If you try to trigger update by manually knowing when data changes, you're probably doing something wrong (or you're optimizing a specific part of the library). Letting Angular do the update is the correct thing to do.
update () {
this.styles = { /* ... */ }
}
<div [ngStyle]="styles">...</div>

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.

Is there a canonical way to get data from a parent in the containment tree?

I have an actionscript-instantiated component in a containment hierarchy; it extends ComboBox, but it's instantiated dynamically--you never know when you're going to need it.
Somewhere up in its containment hierarchy, there's a thing which extends NavigatorContent which logically is the right place to put the valid values for said combo box.
What's the canonical way for that child component to get a reference to that set of valid values?
I would solve this by having the child dispatch a bubbling event (CHILD_CREATED) with a self refrence when it's created. Then simply listen for the CHILD_CREATED event in the object that has access to the set of valid values.
#1 Parent is created - add a listener to know when a child is created and needs a refrence to values
#2 Child is created - dispatches CHILD_CREATED dynamic event with a self refrence as a property
#3 Parent hears CHILD_CREATED - extracts the reference to the child component and sets its data provider to the set of valid values.
EDIT:
A much cleaner way to handle this kind of problem if you are dealing with a component based on DataGroup is to use the rendererAdd (there is a refrence to the renderer in the event). This would definitly be the canonical way to handle it.
So if you are using a DataGroup to display components that you need to access directly, just use the rendererAdd event. If that issn't applicable to your problem, I'd go with the CHILD_CREATED method.
I don't think there is one canonical way to solve this. There are so many possible solutions. You could:
Pass the values as an argument to the child constructor
Pass a reference to the NavigatorContent and then get the values directly upon instantiation
Pass a reference to the NavigatorContent and then add a change listener to it, which fires every time a new value is set
Use a Factory or Factory Method which has a reference to the NavigatorContent to create and populate the child
Create a Proxy or Delegate class to manage creation and data population of all children of the NavigatorContent
...
I'm sure there are tons more.
It all depends on what your program is doing, how the rest of the hierarchy works together, when and if those values are updated, and whatever other requirements need to be fulfilled.
Start from there, then look at the suggestions people have made here, and pick one which suits your scenario best.

may i know what is different viewstack and states in flex?

In my flex project i used one option like Link button . If i like it will be open new page
contain more information and components . Which container is suitable one ?
Where is used viewstack and stages ? if you know please explain it . or refer me
With states you can have objects in each state with the same id - this cannot be done with a viewstack. Usually states are used when a group of objects are shared amongst the different "states" or "views". So for example you can have a textinput in each one of your states and give each one the same id of "username". When you reference the "username" id it will use the object in the currently enabled state. If you try to do this with a viewstack it will throw an error saying you've defined an id of "username" multiple times.
So as a wrap up... use states when you're adding or removing components from a set of components shared throughout each state. Use a viewstack when each view is different and do not share components.
Use states when your views are very similar and only differ based on a few controls or components. If you have too many AddChild / RemoveChild elements it becomes more difficult for a developer to follow your code.
A ViewStack also supports deferred instantiation through the "creationPolicy" attribute. This means that only the first Container in a ViewStack will be initialized when the ViewStack loads. This can really speed up load time of your application if you (A) have a lot of children in the ViewStack or (2) the children are large / complex components.

How to tell when an MXML component has totally finished creation?

An MXML component can be quite complex, containing many nested controls, including asynchronously loaded content such as Image/SWFLoader.
Is there one event I can watch for on my component that will only be raised when every control and sub-component has loaded, including SWFs and Images?
CreationComplete will NOT do the trick if you are talking about loading swf content or anything really external like that. CreationComplete gets fired when the MXML components have been laid out as defined in MXML (IE nested components, buttons, boxes, canvasses, etc.), so content that needs to get loaded externally (an image, a swf) does not count.
What you need to do is keep track of everything that you're waiting for and fire off a custom event once all of those elements have loaded.
One possible hackish way to do it would be to listen for whatever load complete event is relevant for each element, then have them call back to the same function that increments a value equal to the number of components you're waiting for. This means you have to pay more attention if you're modifying it, but it also means you don't have to check a boolean for every element that needs to load (IE "if (image1Loaded && image2Loaded && swfLoaded)" etc.)
The onApplicationComplete event?
The creationComplete event should do the trick - creationComplete is called on the parent component after it is called on the children.
You can get some more info on the component lifecycle in the Adobe docs.
In some complex cases, like when your component is considered "finished" only when some data has been retrieved via HTTP or something like that, custom event is your best bet.

Resources