Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development Knowledge Base

How to pass data to and from a QML Dynamic Component

by Developer on ‎12-18-2013 09:41 AM (4,645 Views)

From time to time in the Native Development Forum a developer will ask how to pass information to a Dynamic Control and it is invariably met with confused answers. So I thought I would write this KB article to show not only how to pass information in but also how to get it back as well.

 

I've reduced the code to the barest essentials to make it clear what is happening and for you to see how it works.

 

Let's start off with a Page that defines the dynamic control's place holder and sets up a Label to display any passed back data from the dynamic control. In fact, we have one dynamic control but we access it in two different ways to show the two different approaches to including controls dynamically.

 

   DynamicLoadingPage.qml

import bb.cascades 1.2

Page {

    Container {
        id: dynamic

        // A function to update a Label with passed back information from our
        // dynamic control
        function receiveValue(passedBackValue) {
            passBackLabel.text = passedBackValue;
        }

        Container {
            layout: StackLayout { orientation: LayoutOrientation.LeftToRight }

            // Create a Button to dynamically load a Control in another QML file
            Button {
                text: "File load"
                onClicked: {
                     // Remove any previous component
                    qmlDelegate.delegateActive = false;
                    // Set the source of our component (file)                     qmlDelegate.sourceComponent = fileLoad;
                    // Load the control in to memory thus adding it to the Scene Graph  qmlDelegate.delegateActive = true; // Here we 'connect' a JavaScript function (slot) to a signal in the                     // dynamic control, to recieve any data passed back qmlDelegate.control.passBack.connect(dynamic.receiveValue); // Here we pass in a value to a property alias defined in the                     // dynamic control. Of course this could also be done using                     // a signal/slot relationship similar to the above line.                     qmlDelegate.control.passedValue = "File Load"; }             }             // Here we do exactly the same thing but reference the Dynamic control             // through an Id
            Button {                 text: "Object load"                 onClicked: {                     // Remove any previous component
                    qmlDelegate.delegateActive = false;
                    // Set the source of our component (Object Id)                     qmlDelegate.sourceComponent = objectLoad; qmlDelegate.delegateActive = true; qmlDelegate.control.passBack.connect(dynamic.receiveValue); qmlDelegate.control.passedValue = "Object Load";                 }             } }         // A Label to show the data passed back from the dynamic control Label { id: passBackLabel text: "Nothing passed back yet!" } attachedObjects: [             ComponentDefinition {                 // A ComponentDefinition to access our dynamic control by filename id: fileLoad source: "DynamicLoadingControl.qml" }, ComponentDefinition {                 // A ComponentDefinition to access our dynamic control by Id id: objectLoad DynamicLoadingControl { } } ] }     // Here we set up a place holder for the dynamic control Container { ControlDelegate {             id: qmlDelegate             // Delegate is only set to active when we have used 1 of the 2 approaches             // to load the dynamic control in to the Scene Graph             delegateActive: false         } } }

 

Now all we need is some control to load dynamically. Here I've chosen a simple Label that just displays any text passed in. We also set up a signal that is emitted whenever that Label text changes, amending it slightly to show it has passed through the dynamic control.

 

   DynamicLoadingControl.qml

import bb.cascades 1.2

Container {
    // A signal for passing back data
    signal passBack(string passValue);

    // A property to update a Label
    // Accessible by the Page adding the dynamic control
    property alias passedValue: lbl.text   

    Label {
        id: lbl
        text: "Nothing passed in yet!"
		
        onTextChanged: {
            // Emit the passBack() signal, passing back amended data
            // whenever the text of the Label changes
            passBack("You passed in: " + text);
        }
    }
}

 

There you have it: a simple dynamic control (in this case a Label) that demonstrates passing of information to and from a dynamically loaded Label. With a couple of screenshots to prove it;

 

Load by Object Id    Load by Filename

 

All the best with loading controls dynamically,

 

Stephen (BBSJDev)

Contributors
Comments
by Developer ‎12-19-2013 06:47 AM - edited ‎12-19-2013 06:48 AM

The techniques demonstrated in this article can also be used for other forms or dynamic component creation as well as just communication between separate QML pages.

by Developer on ‎12-27-2013 05:14 PM

Note that this article is not a particularly good example of working with a dynamic component, creating multiple signals as it does and not removing the created signals cleanly as would have to be considered in a proper project.

 

This was a deliberate decision to focus the article on data passing rather than the intricacies of dynamic components, it's intended that a later article will address those issues.

 

by Developer ‎12-28-2013 10:39 AM - edited ‎12-28-2013 10:41 AM

one downside is that control delegate is not avaliable until 10.2  however you can essentially get away by doing the same thing using just component definitions, property alias, some variants and calling .destroy() when finished with the definition =)

by Developer on ‎12-28-2013 05:14 PM
This will become less and less of an issue as time goes by and I did mention that the way of doing this is transferable to other ways of handling dynamic components as well as just plain talking between objects in either C++ or QML.
by New Developer on ‎05-07-2014 03:56 PM

hay thanks for the help but how can I load a qml file into a container and pass values to it ?

by Developer on ‎05-07-2014 05:30 PM
That's what the code above shows? The first ComponantDefinition uses the load file method.
Users Online
Currently online: 4 members 1,083 guests
Please welcome our newest community members: