knockout-sortable
knockout-sortable copied to clipboard
Sortables and computed arrays
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);
};
}
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.
Can I help ?
@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.
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 .