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

Posts: 91
Registered: ‎09-25-2012
My Device: bb10 alpha
My Carrier: free

LstItemComponent doesn't track the model change....

[ Edited ]

This is my code.... Which make me angry... 

After clear() and repopulate() the CheckBox keep the user change.... So, if you check true, clear the list , and repopulate, the checkbox keep true.... What the hell ?? ListItemComponent doesn't destroy ??



a lover of Qt
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10
My Carrier: none

Re: LstItemComponent doesn't track the model change....

The underlying issue comes from the fact that the visual items (whatever is defined inside ListItemComponent, in this case a single Checkbox) are created independently of the model items, and are reused.  If the list shows only 10 items out of 50 (for example), it pre-creates approximately 20 CheckBox objects, so extras are available quickly during scrolling.  As you scroll through the list, and the visual items are scrolled off the top and no longer visible, it caches those items and jumps them down just below the visible area of the list, then slides them into view after updating their state (name and checked state, in the case of a CheckBox) from the appropriate model data.


In the code as shown, when you toggle the CheckBox, the "checked" state is never being stored back to the model, nor is it being set from the model data in the first place, so if a checked item happens to get reused later on in the list during scrolling, it may appear already checked.


Here's code that's been instrumented to better show the relationship between the visual items (shown with #nn) and the items corresponding to the model data, as well as to properly handle changes to the state of the checkboxes by storing the data back to the model.  Note that the ListView will programmatically change the state of the checkboxes as it reuses them during scrolling, so you also have to check the ListItem.initialized property so you know when to actually respond to the checkbox state changes in the handler (i.e. only when it's actual user input causing the change).


import bb.cascades 1.0

Page {
    Container {
        ListView {
            dataModel: ArrayDataModel {
                id: model
            listItemComponents: [
                ListItemComponent {
                    property int visid: 0

                    Container {
                        id: iroot
                        property string visid

                        leftPadding: 10
                        rightPadding: 10

                        layout: StackLayout {
                            orientation: LayoutOrientation.LeftToRight

                        Label {
                            preferredWidth: 100
                            verticalAlignment: VerticalAlignment.Center
                            text: visid

                        CheckBox {
                            text: ListItemData.name
                            checked: ListItemData.checked
                            onCheckedChanged: {
                                if (!iroot.ListItem.initialized)

                                var item = ListItemData;
                                item.checked = checked;
                                print(iroot.visid, iroot.ListItem.indexPath,
                                    'check', item.name, item.checked);
                                    iroot.ListItem.indexPath, item);

                            onTextChanged: {
                                var item = ListItemData;
                                print(iroot.visid, iroot.ListItem.indexPath,
                                    ' text', item.name, item.checked);

                        onCreationCompleted: {
                            visid = '#' + (++iroot.ListItem.component.visid);
        }// ListView

        Button {
            text: "populate"
            onClicked: {
                for (var i = 0; i < 60; i++) {
                    model.append({name: 'foobar ' + i, checked: false});

        Button {
            text: "clear"
            onClicked: model.clear();
    }// Container
}// Page


Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!