I want to know what are the exact differences between components and controls and also the significance of each in ENYO?
Control descends from Component. Control is a component that has a DOM node associated with it, in the simplest sense. Controls have additional functions, events and properties that are useful for items that will be displayed within a page. Component is the base that introduces the concept of the nested components block and allows a hierarchy.
You might want to start exploring the docs here: http://enyojs.com/docs/
Related
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.
Can anyone clarify this statement from the WatchKit Development Tips page?
Simplify controller scenes.
Reduce the number of hidden objects as much as possible to significantly improve load time. For example, five versions of a controller’s layout in a single controller scene will result in all objects being created before the controller is displayed
I've read it a few dozen times now and can't figure out what it's trying to say.
What is a "scene"? Is it referring to the Storyboard scene?
Are "hidden objects" referring to literally hidden UI elements like a hidden button?
How is it possible to have five versions of a controller's layout? This just does not compute.
When a storyboard is loaded, and there are, say, 10 different WKInterfaceControllers in the file, will that be very slow even if the initial controller is blank? Aren't these only loaded as-needed? Or, would it be better to have a single table with 10 prototype rows - each of which is actually a stand-alone interface - which are only instantiated one at a time?
Because we can't programmatically add interface elements to controllers in the current version of WatchKit, any interface elements that we might need to display must be included in a Storyboard scene. By including these initially-hidden elements, we can programmatically hide or unhide these elements as needed.
For example, it's common to include a full-screen label that is initially hidden. Then, if a full-screen message needs to be shown for some reason, the text is populated, the label is unhidden, and the rest of the elements on the screen are hidden. To make hiding a set of elements easier, they're typically included in a WKInterfaceGroup, so that only the top-level group element needs to be hidden.
So, to answer your questions:
Indeed, a "scene" is a standard Storyboard scene.
Yes, "hidden objects" is referring to literally hidden objects as I've described above.
Using the method I've described, you could create five top-level WKInterfaceGroup elements, each with its own set of controls and layout. Then, you'd likely unhide the one that makes sense to display and hide all the others.
I use these techniques in my own app, though I typically don't have more than three top-level groups.
So yes, because it takes time to initialize and layout all of these elements (even if they're hidden), the recommendation is to keep it to a minimum.
Regarding the loading of interface controllers in a storyboard, you're correct that only the interface controllers that are needed are loaded. However, if you have a set of five page-based controllers, they'll all be loaded and initialized before the first page is activated. Other controllers would then be loaded as appropriate.
Creating unique rows is another possibility, but whether you do that or simply hide/unhide top-level groups depends on your app's specific needs. As always, it's worth testing on actual hardware.
I want to know if its a good idea to have an mxml file for each component, then inline these various components in one mxml file and able to communicate between these mxml files ?
For example I have a overView.mxml and in this, i inline the other mxml files which contains components like datagrid, another mxml contains may be a form. Will i be able to communicate to the grid data by accessing its id in the form mxml ?
Please let me know if my question is not clear. I will try to rephrase it.
Thanks so much.
Yes, this is a good idea. It's much better than creating one giant MXML or class that contains all of your functionality.
At the same time, it caries some overhead. To communicate between the classes (MXML files are just classes) you have to dispatch events. A parent component that contains child components, can set public properties of its child components (with or without data binding).
You should try to decouple your components as much as possible. Try not to write code where the child component is explicitly referring to the parent (ie: try not to use the parent property). Instead dispatch an event from the child component and make the parent listen for the event.
Regarding your example with a data grid and a form:
If these two objects will have a lot of interaction between them, it will be much easier to keep them in the same MXML file. This doesn't sound like a scenario where one is a parent component that contains a child component. Since these "siblings" are likely to communicate w/each other, it would be easier to have them in the same MXML file. However, if things get complex and the file grows to more than a couple hundred lines, you will likely benefit from separating them.
Let's say you plan to use the form component elsewhere in your project w/out the data grid, then it also makes sense to separate them.
Regarding your question: "will the form component be able to communicate w/the grid component by accessing it's id?":
Technically, yes, you could do that but only by tightly coupling your form component w/the grid component. The form component can use the parent property to go up one level and use the id of the grid. But since the parent property is typed as a DisplayObjectContainer you have to fool the compiler and you loose the benefits of strong typing (because the DisplayObjectContainer doesn't have a property that is the ID of your grid). So while this is possible, it's not good design and prevents you from reusing the form component elsewhere.
This tight coupling defeats the purpose of creating separate components. So you're back to either facilitating that communication through dispatching events, or putting the grid and form in the same document :)
TLDR:
You should generally be trying to create re-usable components. So I would generally lean in that direction. MXML files are just classes, all the usual things people talk about in object oriented programming apply.
I'm refactoring some Flex code written by another developer and I'm implementing a PresentationModel approach, as I like to separate out the ActionScript from the MXML. One of the problems I've found is that the original ActionScript code adds/removes elements from the MXML.
What happens is the handler function checks the model and if the values are correct will either create or remove a element from the view. What is the best way to get the presentation model to ad elements to the view and still keep this loose coupling that I'm aiming for.
I was thinking of using simple events which the presentation model dispatches and a view can list for passing the details of the element to add. Is there another solution?
Thanks
Stephen
If you're using the presentation model, I'd assume that you have some kind of data of what needs to happen. When items of any sort are being dynamically added/removed, I make sure to make it data-driven for easier manipulation. If you want another item added, add another data model to your dataProvider of choice (List, ComboBox, DataGroup, etc).
By doing this approach, you're abstracting the logic from the presenter to the view. Events should only be used as a way for your view to know when your presenter has accomplished something. Data can be received this way (and it's good practice to do so) OR you can just bind the data within the presenter to your dataProvider. Both are good, I just find binding to be cleaner and simpler.
Every part of code that do some graphical stuff (drawing border, setting style, drag & drop management, animations, ...), should be included in the view, not the presentation model.
For this kind of graphical that stuff should be executed after a property has been changed in the PM, we use the Cairngorm 3 Observer lib. Basically, it listens to some changes in the presentation model and allows you to execute a function in the View.
<cg:ObserveValue
source="{ model.firstName }" value="{ Name.SARA }"
handler="runEffectFunction"/>
See the documentation
In the examples for RobotLegs, it appears that mediators are used on every button/textArea, rather than on the custom component that contains these children. This would be very time consuming would it not?
From Joel Hooks InsideRia Example
Dependency injection works better with
unambiguous classes. What this means
is that by extending TextArea into our
new MessageView class, we are creating
a specific view component for the
dependency injection to act upon. This
is important if our application were
to have several TextAreas that served
different purposes. By dividing up our
classes in this way, we are clearly
defining the intent of the class and
allowing for the dependency injection
tools to do their jobs effectively.
No, don't mediate every child component. Your components should be organized into groups that perform related actions. In the examples the components are extremely simple and do not reflect what a real application would look like.
One rule of thumbs I use is thinking if that component needs any communication with the rest of the application, or if its only a part of a whole. Keep in mind that mediator are only intended to serve as a bridge between the view and the app.
For example, if I've a view with a form (asume a login form) I don't mediate all the child components (the textfields, the buttons, etc.) because it would be pointless and would have a proliferation of classes and objects on runtime. When I do the form I think, what does the view by its own? and what the other parts of the app should do with it?
When the user fills the form and clicks a button, the view dispatches an event (LoginRequestEvent, for this case), and then the mediator should redispatch that event, making the mediator very lean.
But with practice of the framework, you'll come up with this feel of what you shold mediate. For instance, in one app I mediate every item renderer of a list, and on other I mediate a view stack with two or three navigation contents.
Hope it helps