Open tbozhikov opened 5 years ago
@tbozhikov I think there is an error in the example you linked, in this fragment:
<DockLayout stretch-last-child="true" :key="item.id"
class="scan-list-item">
Actually, item.id
is undefined
so we are using the same key for each element, which I guess give us random results.
Try to change the :key="item.id"
with :key="index"
and see what happens.
I've done this in a local sample I prepared with your code and it worked, at least with the tests I made:
@tbozhikov BTW, the second column is not updated after the input fields are modified. Maybe this is the issue you are talking about.
@tbozhikov I guess that the issue of stale values in the last column is caused by the recycling mechanism in the RADListView. See the next code I've tried:
import { ObservableArray } from "tns-core-modules/data/observable-array/observable-array";
const initialData = [{
name: "first",
value: 1
},
{
name: "second",
value: 2
},
{
name: "third",
value: 3
}];
export default {
name: "Observables Issue",
template: `
<Page>
<ActionBar :title="title">
</ActionBar>
<StackLayout>
<GridLayout class="m-x-5" rows="auto, *, auto, auto">
<Label text="RadListView:" class="m-r-10 text-center" />
<RadListView ref="listView" row="1" for="(item, index) in itemList">
<v-template>
<DockLayout stretch-last-child="true" :key="index"
class="scan-list-item">
<StackLayout orientation="horizontal" dock="right"
class="m-0 stepper-container-combo">
<TextField v-model.number="item.value"
keyboardType="number" width="40" class="m-r-10 text-center" />
<Label :text="item.value" width="40" class="m-r-10 text-center text-muted" />
</StackLayout>
<StackLayout class="p-10">
<Label :text="item.name" />
</StackLayout>
</DockLayout>
</v-template>
</RadListView>
<Label row="2" :text="'First item value: ' + itemList.getItem(0).value" class="m-r-10 text-center text-muted fa-icon" />
<StackLayout row="3">
<Button @tap="onBtnTap" text="add item" height="50"></Button>
<Button @tap="onRefresh" text="refresh" height="50"></Button>
</StackLayout>
</GridLayout>
</StackLayout>
</Page>
`,
data() {
return {
itemList: new ObservableArray(initialData),
};
},
methods: {
onBtnTap() {
this.itemList.push({
name: "new one",
value: 1
});
},
onRefresh () {
this.$refs.listView.refresh();
},
},
};
Please see the screenshot which shows the issue:
@msaelices The way that views are recycled is that only their UI is recycled but their "binding context" or "context" is reset. This means that when a UI is reused for a different item it is impossible to show an incorrect data if the wrapper (in this case the directive for Vue) is setting it correctly. In RadListView this happens here which is called by onItemLoadingInternal which itself is called by the native component here while it is loading a "View" for a corresponding object from the items
collection.
For me the main issue is why is the UI not updated immediately while the input is being changed, if we can force that update to be immediate we will not rely on the "recycling" functionality to update the entire View of the cell. Relying on that is not a good approach because that recycling is handled by the OS and we have no control over it.
Tell us about the problem
Consider this setup -> https://play.nativescript.org/?template=play-vue&id=y9si9q&v=4
In iOS and Android there is an issue with displaying the correct information on each item, maybe related to virtualization problem. To reproduce:
Which platform(s) does your issue occur on?
iOS and Android
Please provide the following version numbers that your is with: