knockout-sortable icon indicating copy to clipboard operation
knockout-sortable copied to clipboard

Sortables and computed arrays

Open patware opened this issue 10 years ago • 4 comments

In a Hierarchical scenario, the sortable works great for patterns where a parent item has a "children" array.

ex: ViewModel has "Manufactures" observableArray, and a manufacturer has "Models" observableArray.

Example of this pattern: http://jsfiddle.net/patware/q8umR/

Now, I've been using another approach for parent/child relationships whenever a child might end up under another parent.

In the ViewModel, I have two collections: allParents and allChildren. Child object has an observable ParentId. The Parent object has a computed function that returns a filtered array of it's own children (vm.allChildren where child.parentId = parent's id)

There are many benefits to this approach:

  • I don't have to deal with the remove from old parent's array and add to new parent's array
  • I can bind the parentId to a box and the "move" gets performed
  • I can easily use ko-lite's DirtyFlag on the child's ParentId field
  • In the ViewModel, I have a computed array of "dirty children" (easy to find)

Here's an example: http://jsfiddle.net/patware/m8wyP/

The problem is that during drop, the afterMove doesn't get called.

From a "framework's point of view", when dealing with arrays, it's easy (ok, somewhat easy, since I've looked at your code and it's more than just a few lines :)) to remove from old Array and add to new Array.

But in my scenario, the Arrays are not "Observable Arrays" per say.

I'm thinking of a "Dropped" method/action where I would receive:

  • The child that got dragged and dropped.
  • The parent on which it was dropped on.

My handler would become:

Parent = function()
{
   var self = this;
   /*...*/
   self.dropped = function(args, event, ui){
      args.item.parentId(args.targetParent.id);
   };
}

patware avatar Apr 10 '14 17:04 patware

I could see calling some handler in the case that the source/target are not observableArrays where it would be up to the dev to determine what it means when it is dropped.

rniemeyer avatar Apr 10 '14 18:04 rniemeyer

Can I help ?

patware avatar Apr 11 '14 11:04 patware

@patware sorry- I missed this one. If you want to try/prototype the changes, then feel free and let me know how it goes and we can go from there. Otherwise, I will certainly take a look myself when I get a chance.

rniemeyer avatar Apr 23 '14 20:04 rniemeyer

Hi! I have the same scenario as patware above. Have you found any solution to this? I'm pondering using the beforeMove-option and in the callback test on child.parentID to decide how to reset it. (In my case I will set a value '1' if it's 'null' and 'null' if it's '1'). Then I should cancel the drop from within the callback to let the ko.computed-filtering logic handle the update. It feels like a hack though, and I'd really want a somewhat cleaner solution.

Also found that when dealing with ko.computed in ko.sortable I have a splice-error (line 244 I think). unwrapping the value collected for 'sourceParent' and 'targetParent' does the trick .

asleg avatar Feb 22 '16 09:02 asleg