Hello,
in some of our pages in the NativeScript app we load data from the server and load it into a RadListView.
Usually we define our Observable (the bindingContext of the page) like this:
exports.vmList = observableModule.fromObject({
loading:
false
,
countries:
new
observableArrayModule.ObservableArray(),
loadCountries:
function
() {
var
self =
this
;
self.set(
"loading"
,
true
);
httpModule.request({ url:
"https://restcountries.eu/rest/v2/all"
, method:
"GET"
}).then(
function
(response) {
//clear array and fill with new data
self.get(
"countries"
).splice(0, self.get(
"countries"
).length);
self.get(
"countries"
).push(response.content.toJSON());
self.set(
"loading"
,
false
);
},
function
(e) {
console.log(e);
self.set(
"loading"
,
false
);
});
}
});
and we set it on navigating event of the page:
exports.onNavigatingTo = function (args) {
page = args.object;
page.bindingContext = vmModule.vmList;
vmModule.vmList.loadCountries();
};
Here is the problem:
When navigating to the page for the first time, everything is working as expected. But when calling the page for a second/third/... time, there is some mismatching on the list items layout, as some of the list items are indended. When scrolling down and up, the position of the indended items changes, so it affects some other list items. You can have a look at the provided GIF animation to better understand what is happening on iOS.
It might be related on what the list item's layout looks like, because we structure it like this:
<
StackLayout
className
=
"listitem-outer"
>
<
StackLayout
className
=
"listitem"
>
<
Label
text
=
"{{ name }}"
fontSize
=
"12"
fontWeight
=
"bold"
/>
<!-- ... -->
</
StackLayout
>
</
StackLayout
>
We noticed, that the issue does not occur when we delete the outer StackLayout. But we need this to give the list item a padding, so that it looks like a CardLayout.
Something else that we have noticed is, that the issue does not occur when we make the page bindingContext a class that inherits from the Observable class...
class VM extends observableModule.Observable {
constructor() {
super
();
this
.loading =
false
;
this
.countries =
new
observableArrayModule.ObservableArray()
}
loadCountries() {
//...
}
}
exports.VM = VM;
... which is initialized everytime we navigate to the page...
exports.onNavigatingTo =
function
(args) {
page = args.object;
page.bindingContext =
new
vmModule.VM();
page.bindingContext.loadCountries();
};
... as we have seen this in some NativeScript tutorials.
We created some sample projects with the issue here
We could set the data binding this way on all pages to overcome the described RadListView issue here, but we are just not sure if this is really best practice to create new instances of the ViewModel on every page navigation, as our previous method is re-using the existing object.
So is this issue related to a bug in the iOS RadListView definition or is the way we are setting the data binding right now just bad practice?
Thank you in advance for any feedback or recommendation and best regards