bevacqua / angularjs-dragula

:ok_hand: Drag and drop so simple it hurts
https://bevacqua.github.io/angularjs-dragula
MIT License
509 stars 110 forks source link

Models and containers in different order making dropped elements show up in wrong containers #93

Open elciok opened 8 years ago

elciok commented 8 years ago

I'm having an issue, but I can't provide a working demo, because it looks like a race condition. But I think I can't explain what is probably happening by referencing back to the code.

Context: using angularjs 1.5.8, angular-dragula 1.2.8. Google Chrome 53.0.2785.143 (64-bit) and Firefox 49.0.1 on Mac OS X 10.11.6. I'm using angular-dragula to drag elements between multiple containers, each container an array using dragula-model attribute.

The issue: sometimes, when dragging and dropping an element to another container, it shows up in another container instead of the container it was dropped on. Sometimes the model dropped turns into an undefined reference.

In my debug sessions, I found out that angular-dragular loads drake.containers at the time of linking (https://github.com/bevacqua/angular-dragula/blob/fccd088c4776eb7d1d282325ac33c6afbd181a48/directive.js#L28), and drake.models on a watch callback (https://github.com/bevacqua/angular-dragula/blob/fccd088c4776eb7d1d282325ac33c6afbd181a48/directive.js#L47).

In this line https://github.com/bevacqua/angular-dragula/blob/fccd088c4776eb7d1d282325ac33c6afbd181a48/service.js#L44 , that service expects the container and its respective model to be at the same index in both arrays (drake.models and drake.containers), but sometimes, depending on the initial values on dragula-model attributes, they might not be in the same indices, because at linking time, when containers are added, its respective model might still be null and it will just return on this line https://github.com/bevacqua/angular-dragula/blob/fccd088c4776eb7d1d282325ac33c6afbd181a48/directive.js#L35 .

I don't know if angular watches and linking order are deterministic, but as a workaround I added an ng-if to the element with the dragula-model attribute, so it is only linked and fires watch when that model actually has a value. But ng-if creates another scope, so I had to add dragula-scope="$parent.$parent" to make dragging to another container work. It seems to mitigate the problem, but I've seen the issue happening after doing that.

Thanks for building this library. It feels so much better than any other DnD library I've used!

DavidMikeSimon commented 8 years ago

I had a similar issue, and the problem turned out to be that one of the dragula-models was set to null before the dragula directive was initialized. When that scope attribute was later populated by an http callback, it seems to sometimes confuse angular-dragula's association map between containers and models. Setting the attribute to an empty array from the start resolved the immediate issue.

Dzignz commented 10 months ago

I had a similar issue, and the problem turned out to be that one of the dragula-models was set to null before the dragula directive was initialized. When that scope attribute was later populated by an http callback, it seems to sometimes confuse angular-dragula's association map between containers and models. Setting the attribute to an empty array from the start resolved the immediate issue.

Thanks! This was causing me endless grief trying to work out why items were randomly disappearing and arriving in other containers!