Nativescript-vue: Reactive <v-template> inside a ListView

Created on 17 Jul 2019  路  8Comments  路  Source: nativescript-vue/nativescript-vue

Version

2.3.0

Reproduction link

https://play.nativescript.org/?template=play-vue&id=rUVzXD

Platform and OS info

Both

Steps to reproduce

  1. Run the sample app.
  2. Click on the "Reverse" button
  3. See that the first label is reactive but not the labels inside the insider the ListView

What is expected?

The labels inside the ListView should be reactive

What is actually happening?

The labels inside the ListView are not reactive

See the screencast:

listview-reactivity-issue mov

Implementation details

NS Core reactivity is based on its data binding mechanism, which is usually performed in the bindingContext. The NS-vue binding BTW does not make use of this variable, delegating the reactivity to the Vue.js library. This is working in examples like that:

<template>
   ... 
   <Label :text="text" />
   ...
</template>
<script>
export default {
   data: {
      return {
         text: 'Hello world',
      }
   },
   mounted: {
      setTimeout(() => { this.text = 'Bye world' }, 5000);
   }
}
</script>

After 5 seconds, the text Vue data is changed and Vue triggers the logic to know if this change affects to the template, which is the case, and finally calls to the setAttribute('text', 'Bye world') (see implementation), which does the trick changing the NativeScript component attribute.

The problem appears when we change an attribute referenced inside a <v-template> node in a ListView component.

But, why most of the apps are working ok with the ListView? Because we usually change the elements in the list, which is passed in the items attribute, and we have this hack here for refreshing the list:

watch: {
    items: {
      handler(newVal) {
        this.$refs.listView.setAttribute('items', newVal)
        this.refresh()
      },
      deep: true
    }
  },
normal

Most helpful comment

This should be addressed as soon as possible. From my understanding it is in the plan for the next major release of nativescript-vue. Currently there are many related issues in both ListView and RadListView which source of this behavior.

All 8 comments

@msaelices i just started to face the same issue.
This needs a fix. The "dirty" solution as @msaelices said is really dirt and goes against cell reuse

This should be addressed as soon as possible. From my understanding it is in the plan for the next major release of nativescript-vue. Currently there are many related issues in both ListView and RadListView which source of this behavior.

Can anyone help with an alternative here? We have a custom component rendered multiple times within a ListView that seemingly doesn't trigger reactivity. I.e. an array of data for the custom component is retrieved from an API and a custom component created for each item in that array.
It sits within a v-template which is in turn inside a ListView but the UI is never updated to show the data.

Definitely need something for this. A manual refresh() call is clunky and can worsen app responsiveness

Is there any timeline about addressing this issue?

Hi,
currently i solved the issue using observableArray. I was using <v-template> inside RadListView and stumbled upon the same issue . I needed to change one property when item was selected.
So basically what you should do is this.

    onItemSelected({ index }) {
      // eventName, object, index, groupIndex, view
      const currentSelectedItem = this.items.getItem(index);
      currentSelectedItem.selected = true;
      this.items.setItem(index, currentSelectedItem);

    },
  • here items is an observableArray
  • So what you need to do is basically get the item, change property you want and set it back at the same position.
  • Bear in mind that in RadlistView, if you are using staggered layout there might be lot of rearrangement if the property you set is going to change the size of template layout you defined.

This is a big problem

This is a big problem

@StephenCarboni Not that big, since it's simple to work around this limitation. If you have ideas how to solve it without re-rendering the whole list on every component data change, please do share them, but it's not simple to account for all possible cases. Applying a workaround when necessary is less error-prone, and has the least performance impact.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mpaccione picture mpaccione  路  3Comments

jarden-liu picture jarden-liu  路  3Comments

vhristov5555 picture vhristov5555  路  4Comments

HunterJS-bit picture HunterJS-bit  路  3Comments

MatheusPimentel picture MatheusPimentel  路  5Comments