问题
I need to detect when items are moved in an observableArray. In my current version (2.1.0) I accomplish this by calling setTimeout
on all delete events and waiting to see if an add event follows immediately on its heels:
var delayed = [];
var key; /* obtained by comparing original observableArray with updated list and iterating all differences */
if( /** record exists in original list but not new list ) {
// it was deleted, we don't immediately fire a notification (it may get re-inserted in a moment)
delayed[key] = setTimeout(function() { sendDeleteNotification(key); }, 0);
}
else if( /** record exists in new list but not original */ ) {
if( delayed[key] ) {
// it was deleted and immediately re-added (it's a move)
clearTimeout(delayed[key]);
sendMoveNotification( key );
}
else {
// it was added
sendAddedNotification( key );
}
}
In knockout 2.2, I see new events for beforeMove and afterMove. However, I can't find any means to utilize them programmatically.
The end goal is to be able to mirror client changes in the database immediately, but not show an add/delete in place of a move event. A record moved up or down in the list shouldn't be marked as deleted and then newly added.
Can the new beforeMove/afterMove bindings be utilized in JavaScript directly (e.g. event model?) to improve this?
Cheers,
回答1:
The answer I utilized was based on this so question and this jsfiddle.
The beforeMove
and afterMove
functions can be accessed by a simple subscription:
var obs = ko.observableArray();
obs.subscribe(function( arrayOfValues ) {
console.log('moving', arrayOfValues);
}, undefined, 'beforeMove');
obs.subscribe(function( arrayOfValues ) {
console.log('moved', arrayOfValues);
}, undefined, 'afterMove');
However, it turns out this wasn't particularly useful as it returns all the elements in the array that change index. For instance, if I delete a record from the list, I get a moved event for every record after the deleted one.
So I'll be sticking with the timeout until I find something better.
来源:https://stackoverflow.com/questions/13391711/utilizing-beforemove-aftermove-without-a-binding