Typical scenarios where this may be desirable are:
- When populating a list view with data from a network service.
- Show a Fetch data button if the list view is empty.
- Present any error that might occur while downloading/processing the data
- Showing search result in a list view.
- Present a No items found text to the user if the list view is empty.
In the example application I'm using an ArrayDataModel, but it should work for QListDataModel and GroupDataModel too. Unfortunately, it will not work with XmlDataModel because the class doesn't expose any function to query if the model is empty (at least not easily).
All of the data models mentioned above provides an isEmpty() function which can be used to check if the data model contain any items or not.
The example should speaks for itself, so without any further ado, here's the code:
All of the data models mentioned above provides an isEmpty() function which can be used to check if the data model contain any items or not.
The example should speaks for itself, so without any further ado, here's the code:
import bb.cascades 1.0 Page { Container { layout: DockLayout {} ListView { dataModel: ArrayDataModel { id: model // Bindable property which tells if the // model is empty or not property bool empty: true // Populates model with dummy data function populate() { for (var i = 0; i < 10; i++) { append({'title' : 'Item #' + i}) } } // The following signal handlers updates // the empty property to correct state onItemAdded: empty = isEmpty() onItemRemoved: empty = isEmpty() onItemUpdated: empty = isEmpty() // You might see an 'unknown signal' error // in the QML-editor, guess it's a SDK bug. onItemsChanged: empty = isEmpty() } } // Only visible when data model is empty. // This should be declared after the ListView // to prevent the ListView from consuming touch input etc // Setting ListView's visible property to !model.empty will // also work. Label { visible: model.empty //model.isEmpty() will not work horizontalAlignment: HorizontalAlignment.Fill verticalAlignment: VerticalAlignment.Center text: qsTr("No entries yet\n\nPlease populate data model") textStyle.base: SystemDefaults.TextStyles.BigText textStyle.textAlign: TextAlign.Center multiline: true } } actions: [ // Action to populate/clear data model depending on state. // Same here, model.isEmpty() will not behave as expected. ActionItem { title: model.empty ? qsTr("Populate") : qsTr("Clear") onTriggered: model.empty ? model.populate() : model.clear() ActionBar.placement: ActionBarPlacement.OnBar } ] }
Screenshots from the example application
A work-around is required because isEmpty() is only an invokable function in QML, and not a bindable property. The example will not behave as expected if model.isEmpty() is set as a value for the Label's visible property. The isEmpty() function is only called once when the Label is created and will never be re-evaluated again since it's not a bindable property (hint to Cascades API developers).
Please feel free to add other ways to accomplish this in the comments section.