Resolve Knockout/#2560 with

45e86bf034
This commit is contained in:
djmaze 2021-09-13 15:52:40 +02:00
parent 47b75755c4
commit f09820d0b9

View file

@ -60,7 +60,8 @@
var nodesToDelete = [];
var itemsToMoveFirstIndexes = [];
var itemsForBeforeRemoveCallbacks = [];
var itemsForMoveCallbacks = [];
var itemsForBeforeMoveCallbacks = [];
var itemsForAfterMoveCallbacks = [];
var itemsForAfterAddCallbacks = [];
var mapData;
var countWaitingForRemove = 0;
@ -69,14 +70,16 @@
mapData = { arrayEntry: value, indexObservable: ko.observable(currentArrayIndex++) };
newMappingResult.push(mapData);
if (!isFirstExecution) {
itemsForAfterAddCallbacks.push(mapData);
itemsForAfterAddCallbacks[currentArrayIndex - 1] = mapData;
}
}
function itemMovedOrRetained(oldPosition) {
mapData = lastMappingResult[oldPosition];
if (currentArrayIndex !== mapData.indexObservable.peek())
itemsForMoveCallbacks.push(mapData);
if (currentArrayIndex !== mapData.indexObservable.peek()) {
itemsForBeforeMoveCallbacks[mapData.indexObservable.peek()] = mapData;
itemsForAfterMoveCallbacks[currentArrayIndex] = mapData;
}
// Since updating the index might change the nodes, do so before calling fixUpContinuousNodeArray
mapData.indexObservable(currentArrayIndex++);
ko.utils.fixUpContinuousNodeArray(mapData.mappedNodes, domNode);
@ -86,7 +89,7 @@
function callCallback(callback, items) {
if (callback) {
for (var i = 0, n = items.length; i < n; i++) {
items[i].mappedNodes.forEach(node => callback(node, i, items[i].arrayEntry));
items[i] && items[i].mappedNodes.forEach(node => callback(node, i, items[i].arrayEntry));
}
}
}
@ -129,7 +132,7 @@
if (mapData.arrayEntry === deletedItemDummyValue) {
mapData = null;
} else {
itemsForBeforeRemoveCallbacks.push(mapData);
itemsForBeforeRemoveCallbacks[mapData.indexObservable.peek()] = mapData;
}
}
if (mapData) {
@ -167,7 +170,7 @@
ko.utils.domData.set(domNode, lastMappingResultDomDataKey, newMappingResult);
// Call beforeMove first before any changes have been made to the DOM
callCallback(options['beforeMove'], itemsForMoveCallbacks);
callCallback(options['beforeMove'], itemsForBeforeMoveCallbacks);
// Next remove nodes for deleted items (or just clean if there's a beforeRemove callback)
nodesToDelete.forEach(options['beforeRemove'] ? ko.cleanNode : ko.removeNode);
@ -184,7 +187,7 @@
mapData = newMappingResult[i];
for (lastNode = undefined; i; ) {
if ((mappedNodes = newMappingResult[--i].mappedNodes) && mappedNodes.length) {
lastNode = mappedNodes[mappedNodes.length-1];
lastNode = mappedNodes[mappedNodes.length - 1];
break;
}
}
@ -229,11 +232,13 @@
// as already "removed" so we won't call beforeRemove for it again, and it ensures that the item won't match up
// with an actual item in the array and appear as "retained" or "moved".
for (i = 0; i < itemsForBeforeRemoveCallbacks.length; ++i) {
itemsForBeforeRemoveCallbacks[i].arrayEntry = deletedItemDummyValue;
if (itemsForBeforeRemoveCallbacks[i]) {
itemsForBeforeRemoveCallbacks[i].arrayEntry = deletedItemDummyValue;
}
}
// Finally call afterMove and afterAdd callbacks
callCallback(options['afterMove'], itemsForMoveCallbacks);
callCallback(options['afterMove'], itemsForAfterMoveCallbacks);
callCallback(options['afterAdd'], itemsForAfterAddCallbacks);
}
})();