RadListView Load on Demand
The load-on-demand feature is particularly useful in cases when data needs to be loaded in chunks (pages) to optimize bandwidth usage and improve the UX. The value of the loadOnDemandMode
property determines the mode that will be used for loading on demand. It accepts the values from the ListViewLoadOnDemandMode
enumeration:
-
Manual
- in this mode the user needs to manually request the next data page -
Auto
- in this mode the next data page is automatically requested as the user approaches the end of the scrollable list -
None
- in this mode load on demand is disabled
When more items need to be loaded, RadListView fires the loadMoreDataRequested
event. That event will continue to be fired until you set the returnValue
of the arguments to false
and call the notifyLoadOnDemandFinished(disableLoadOnDemand)
with a true
parameter, you can use this when you have reached the end of your data stream and there will no longer be any data to be loaded.
In addition, RadListView
exposes the loadOnDemandBufferSize
property which determines the count of items left to scroll which when reached triggers a loadMoreDataRequested
event. This property is used when the load-on-demand mode is set to be Auto
.
Handling the loadMoreDataRequested
Event
The following code snippet demonstrates how the loadMoreDataRequestedEvent
event is handled. We first need to subscribe for the event as the following XML snippet shows:
Example 1: Subscribing for loadMoreDataRequested in XML:
<lv:RadListView id="ls" items="{{ dataItems }}" row="0" loadOnDemandMode="Manual" loadMoreDataRequested="{{onLoadMoreItemsRequested}}">
in our event handler we make a data request and when the data chunk is ready we feed the list:
Example 2: Handling the loadMoreDataRequested in XML:
public addMoreItemsFromSource(chunkSize: number, listView: RadListView) {
let newItems = this._sourceDataItems.splice(0, chunkSize);
this.dataItems.push(newItems);
if (listView) {
// Call the optimized function for on-demand loading finished.
// (with 0 because the ObservableArray has already
// notified about the inserted items)
listView.notifyAppendItemsOnDemandFinished(0, this._sourceDataItems.length === 0);
}
}
public onLoadMoreItemsRequested(args: LoadOnDemandListViewEventData) {
const that = new WeakRef(this);
const listView: RadListView = args.object;
if (this._sourceDataItems.length > 0) {
setTimeout(function () {
that.get().addMoreItemsFromSource(20, listView);
}, 0);
args.returnValue = true;
} else {
args.returnValue = false;
listView.notifyAppendItemsOnDemandFinished(0, true);
}
}
Here, the usage of a timer is for the purpose of simulating a call to a remote service. The
notifyLoadOnDemandFinished(disableLoadOnDemand)
call is made to inform the list view that the requested data chunk has been delivered.
Customizing the Load-on-Demand View
To customize the load-on-demand view displayed at the end of the list you need to use the loadOnDemandItemTemplate
property. Here's a simple example:
Example 3: Providing a custom loadOnDemandItemTemplate:
<lv:RadListView.loadOnDemandItemTemplate>
<GridLayout style="background-color: #7fff7f;" height="44" bottomMargin="20">
<Label text="Load More" horizontalAlignment="center" verticalAlignment="center"/>
</GridLayout>
</lv:RadListView.loadOnDemandItemTemplate>
The loadOnDemandItemTemplate
property is used just like the itemTemplate
property. Note that the binding context of the view generated from this template is the one assigned to the page.
References
Want to see this scenario in action? Check our SDK examples repo on GitHub. You will find this and many other practical examples with NativeScript UI.
Related articles you might find useful: