0
votes

I'm trying to render a list of images, using RadListView. Being that i had some bizarre behavior when the data was coming from a normal array, i decided to try ObservableArray, as recommended in the docs.(specifically tns-vue)

The problem is, that pushing a new item to the model, doesn't update the view. The item is there, but nothing is shown.

This is my RadListView:

 <RadListView layout="grid" ref="newImages" for="image in newImages">
              <v-template>
                <ImageComponent
                  showDate="false"
                  :onLongPress="()=>{onLongPress(image)}"
                  :image="image"
                ></ImageComponent>
              </v-template>
            </RadListView> 

The "newImages" array:

 data() {
    return {    
      newImages: new ObservableArray([]),     
    };
  }

I add items to the array, using the camera plugin:

openGallery() {
      var that = this;
      console.log(that.newImages.length);
      var context = imagepicker.create({ mode: "multiple" }); // use "multiple" for multiple selection
      context
        .authorize()
        .then(function() {
          return context.present();
        })
        .then(function(selection) {
          const images = [];
          selection.forEach(function(selected) {
            const image = that.createNewFileSchema(selected._android);
            images.push(image);
          });
           that.newImages.push(images)//This adds the images to the array, but UI doesn't respond to the change.

        })
        .catch(function(e) {
          alert(e);
        });
    },

What could be the problem here?

1
Can you share a minimal Playground sample where the issue can be reproduced? - Manoj
To be honest, i ain't sure how to do it, being that the problem occurs ONLY from this camera-plugin callback. It doesn't occur, if i "push" a new image manually from a dummy function. Exactly the same object structure, but for some reason it works. Maybe this can give you some clue? Can it somehow be related to the asynchronous nature of the camera function? Though i tried using an asynchronous dummy function, and it worked... - i.brod
Manoj, i see that everything works fine when using the normal ListView instead of RadListView. The only reason i needed the RadListView is because of the layout="grid" option(which allows me to render the images in "pairs of two"). What would be an alternative to using Rad, but still achieving this grid look? Is my only option is to group my data array into pairs, and then have nested loops? - i.brod
This is just out of the blue sheff2k1, but would you mind tying to key your iterator? so <RadListView v-for="(image, index) of newImages" :key="index"> - Abarth
But this would produce multiple RadListView components i think..anyway doesnt work - i.brod

1 Answers

1
votes

Your pushing arrays to a data arrays, to make the virtual DOM notice these changes, you probably wan't to use a deep watcher, calling a method returning the updated array.

You would have the same problem with Objects, but then you would be able to use:

this.$set(<object>, <key>, <value>)

I'm unsure if there is a better way for arrays, but you could try a watcher as said

watch: {
   newImages: {
      handler: function(<value>, <oldValue>) {},
      deep: true
   }
}

UPDATED - You can use this.$set for arrays https://vuejs.org/v2/api/#Vue-set

/*   this.$set(<Array>, <Index>, <Value>)   */

this.$set(this.newImages, this.newImages.length, [...newArrWithImages])

This guy explains reactively updating arrays: Vuejs and Vue.set(), update array