Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug when replacing last item in v-for [vue 1.0.13] #27

Open
Leotomas opened this issue Oct 12, 2017 · 3 comments
Open

Bug when replacing last item in v-for [vue 1.0.13] #27

Leotomas opened this issue Oct 12, 2017 · 3 comments

Comments

@Leotomas
Copy link

Hi,
We're using vue 1.0.13 and ended up using your library, thanks for your work.

We've encountered an issue when dragging an item in a v-for from any position into the last position of the list. It seems that the last item is placed after the "v-for end" comment in the DOM. It does not affect the behaviour of further dragging and dropping items in the list, however when we try to push something in the list, the console throws an exception.

Here's a screenshot showing the li item being moved below the v-for comment line : https://imgur.com/a/I1Odo

Here's a pen reproducing our setup : https://codepen.io/Leotomas/pen/veayav?editors=1111

And here's a little video showing the bug : https://www.youtube.com/watch?v=2jhnJ9adrWM&feature=youtu.be

We have found a workaround. In the method that pushes the new item inside the list, we toggle the visibility of the list with a v-if, when then list reappears the dom issue is resolved.

addTask(instance) {                                                                                                                                                                                                                                         
                   let i = _.findIndex(this.data.instances, {id: instance.id});                                                                                                                                                                                            
                   let item = {                                                                                                                                                                                                                                            
                       id: uuid.v4(),                                                                                                                                                                                                                                      
                       libelle: instance.__new_item,                                                                                                                                                                                                                       
                       checked: false                                                                                                                                                                                                                                      
                   }                                                                                                                                                                                                                                                       
                   let p =  this._clone(this.data.instances[i].taches);                                                                                                                                                                                                    
                   p.push(item);                                                                                                                                                                                                                                           
                   this.states.ready = false;                                                                                                                                                                                                                              
                   this.$nextTick(() => {                                                                                                                                                                                                                                  
                       this.states.ready = true;                                                                                                                                                                                                                           
                       this.$set('data.instances[' + i +'].taches', p);                                                                                                                                                                                                    
                       instance.__new_item = null;                                                                                                                                                                                                                         
                   });                                                                                                                                                                                                                                                     
               },

So it seems that when sortable moves any item in the last position, the relationship between vue and the DOM is broken somehow.

Thanks in advance

@rafatrace
Copy link

This happens to me too, have you managed to find a solution @Leotomas ?

@Leotomas
Copy link
Author

Leotomas commented Dec 7, 2017

@rafamds yes as written above, "we have found a workaround". To explain further :

  • put a v-if in the parent div of the sortable element
  • in the vue method that pushes something in your sortable list, create your new element then toggle this v-if to false (don't push the newly created element yet)
  • in a $nextTick call, toggle the v-if back to true, then push the new item in your list.

It somehow resets the dom properly and the bug goes away.

@bradlis7
Copy link

I was having this problem as well... I would make a bet that the rubaxa is applying the sort to the DOM, and then when Vue tries to reorder, it's using "in-place patch strategy".

@Leotomas solution causes Vue to recreate the DOM, which is probably fine.

The best solution may be to provide a key attribute with v-for (https://vuejs.org/v2/guide/list.html#key).

There might be a fix that this library can make so that rubaxa doesn't actually update the DOM, but I have not looked into it that far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants