ui-sortable with 2 firebaseArray models
See original GitHub issueHey there, so as mentioned in https://github.com/firebase/angularfire/issues/200 and https://github.com/angular-ui/ui-sortable/issues/421 using ui.sortable with firebaseArray currently is a bit messy, since the latter relies on .splice to move an array value from one ng-model to another ng-model, which doesn’t get synced when used with a firebaseArray.
The use case is using multiple ui.sortable lists and to be able to move one item from one list, to another list. E.g. to easily create similar functionality to Trello, or other PM boards. Currently if I drag & drop an item from ng-model1 to ng-model2, then firebase gets out of sync, since the arrays have been spliced in that operation.
The current work-around that works for me is an ui-sortable.js override, which isn’t so pretty. See the 2nd revision of this gist https://gist.github.com/mastef/0ae8ba7595cafad2c85f/revisions?diff=unified ( the first revision is the sortable.js itself, the 2nd revision are the $firebaseArray necessary changes )
2 reasons why this is not a nice work-around : It overrides ui-sortable to solely work with $firebaseArrays, so it won’t work with normal arrays any longer, and secondly it hacks the core script.
Explanation of the edit :
We pick up an item in a list and drop it on another ng-model.
What happens in the code : Locate the item in the old model through $getRecord
, save it in a temporary internal var and remove it from the old list.
We drop the item on another list, so we a) find out if there’s an item located at the drop offset of the new list. If yes, we drop the current item with a smaller priority than the item we dropped it over.
If not, we assume that we dropped at the end of the list. Dropping temporary item with a maximum priority of 99999.
And b) finally we add the item with the new priority to the new ng-model.
Last but not least we recalculate priorities on each list change based on current index offset.
So this works very specifically with $firebaseArray and ui.sortable + multiple lists. Another way to achieve this would be to override the .splice, etc functions for $firebaseArray. But @katowulf I suppose you would know more about the issues this approach would come with.
Issue Analytics
- State:
- Created 8 years ago
- Reactions:1
- Comments:5 (2 by maintainers)
Top GitHub Comments
I fiddled with a few different ideas. This is really the best approach. Trying to save after each individual splice or op gets a bit schizophrenic (keep in mind we’re getting changes from the server, too, so you’re essentially trying to send data two directions through the same pipe).
It’s also hard to tell when to actually perform the save without knowing all the details of the implementation. For example, when you splice a record out, should it be immediately removed? To drag a record, you first splice it out and then put it back in at a different location (ideally that would trigger child_moved rather than child_removed and child_added).
Thus, a checkpoint/save is the most sane, as you suspected. If you want to automate this in some way, I’d try a debounce on saveChanges() that has a liberal pause.
I’d guess, however, that there are some events you can monitor on angular UI libs that could help here. For example, I’d guess that drag/drop tools will have some sort of “drag completed” event that triggers.
Absolutely fantastic! Have been working around this issue for months. Thanks!