KnoutJS cleanup templating.js a bit

This commit is contained in:
the-djmaze 2024-03-03 16:46:54 +01:00
parent 97a369048e
commit 0f0f60e456

View file

@ -112,68 +112,69 @@
} else { } else {
console.log('no targetNodeOrNodeArray'); console.log('no targetNodeOrNodeArray');
} }
}; },
ko.renderTemplateForEach = (template, arrayOrObservableArray, options, targetNode, parentBindingContext) => { renderTemplateForEach = (template, arrayOrObservableArray, options, targetNode, parentBindingContext) => {
// Since setDomNodeChildrenFromArrayMapping always calls executeTemplateForArrayItem and then // Since setDomNodeChildrenFromArrayMapping always calls executeTemplateForArrayItem and then
// activateBindingsCallback for added items, we can store the binding context in the former to use in the latter. // activateBindingsCallback for added items, we can store the binding context in the former to use in the latter.
var arrayItemContext; var arrayItemContext;
// This will be called by setDomNodeChildrenFromArrayMapping to get the nodes to add to targetNode // This will be called by setDomNodeChildrenFromArrayMapping to get the nodes to add to targetNode
var executeTemplateForArrayItem = (arrayValue, index) => { var executeTemplateForArrayItem = (arrayValue, index) => {
// Support selecting template as a function of the data being rendered // Support selecting template as a function of the data being rendered
arrayItemContext = parentBindingContext['createChildContext'](arrayValue, { arrayItemContext = parentBindingContext['createChildContext'](arrayValue, {
'extend': context => context['$index'] = index 'extend': context => context['$index'] = index
}); });
var templateName = resolveTemplateName(template, arrayValue, arrayItemContext); var templateName = resolveTemplateName(template, arrayValue, arrayItemContext);
return executeTemplate(targetNode, false, templateName, arrayItemContext, options); return executeTemplate(targetNode, false, templateName, arrayItemContext, options);
}; };
// This will be called whenever setDomNodeChildrenFromArrayMapping has added nodes to targetNode // This will be called whenever setDomNodeChildrenFromArrayMapping has added nodes to targetNode
var activateBindingsCallback = (arrayValue, addedNodesArray) => { var activateBindingsCallback = (arrayValue, addedNodesArray) => {
activateBindingsOnContinuousNodeArray(addedNodesArray, arrayItemContext); activateBindingsOnContinuousNodeArray(addedNodesArray, arrayItemContext);
// release the "cache" variable, so that it can be collected by // release the "cache" variable, so that it can be collected by
// the GC when its value isn't used from within the bindings anymore. // the GC when its value isn't used from within the bindings anymore.
arrayItemContext = null; arrayItemContext = null;
}; };
var setDomNodeChildrenFromArrayMapping = function (newArray, changeList) { var setDomNodeChildrenFromArrayMapping = (newArray, changeList) => {
// Call setDomNodeChildrenFromArrayMapping, ignoring any observables unwrapped within (most likely from a callback function). // Call setDomNodeChildrenFromArrayMapping, ignoring any observables unwrapped within (most likely from a callback function).
// If the array items are observables, though, they will be unwrapped in executeTemplateForArrayItem and managed within setDomNodeChildrenFromArrayMapping. // If the array items are observables, though, they will be unwrapped in executeTemplateForArrayItem and managed within setDomNodeChildrenFromArrayMapping.
ko.dependencyDetection.ignore(ko.utils.setDomNodeChildrenFromArrayMapping, null, [targetNode, newArray, executeTemplateForArrayItem, options, activateBindingsCallback, changeList]); ko.dependencyDetection.ignore(ko.utils.setDomNodeChildrenFromArrayMapping, null, [targetNode, newArray, executeTemplateForArrayItem, options, activateBindingsCallback, changeList]);
ko.bindingEvent.notify(targetNode, ko.bindingEvent.childrenComplete); ko.bindingEvent.notify(targetNode, ko.bindingEvent.childrenComplete);
}; };
if (ko['isObservableArray'](arrayOrObservableArray)) { if (ko['isObservableArray'](arrayOrObservableArray)) {
setDomNodeChildrenFromArrayMapping(arrayOrObservableArray.peek()); setDomNodeChildrenFromArrayMapping(arrayOrObservableArray.peek());
var subscription = arrayOrObservableArray['subscribe'](changeList => { var subscription = arrayOrObservableArray['subscribe'](changeList => {
setDomNodeChildrenFromArrayMapping(arrayOrObservableArray(), changeList); setDomNodeChildrenFromArrayMapping(arrayOrObservableArray(), changeList);
}, null, "arrayChange"); }, null, "arrayChange");
subscription.disposeWhenNodeIsRemoved(targetNode); subscription.disposeWhenNodeIsRemoved(targetNode);
return subscription; return subscription;
} }
return ko.computed(() => { return ko.computed(() => {
var unwrappedArray = ko.utils.unwrapObservable(arrayOrObservableArray) || []; var unwrappedArray = ko.utils.unwrapObservable(arrayOrObservableArray) || [];
if (typeof unwrappedArray.length == "undefined") // Coerce single value into array if (!Array.isArray(unwrappedArray)) // Coerce single value into array
unwrappedArray = [unwrappedArray]; unwrappedArray = [unwrappedArray];
setDomNodeChildrenFromArrayMapping(unwrappedArray); setDomNodeChildrenFromArrayMapping(unwrappedArray);
}, { disposeWhenNodeIsRemoved: targetNode }); }, { disposeWhenNodeIsRemoved: targetNode });
}; },
var templateComputedDomDataKey = ko.utils.domData.nextKey(); templateComputedDomDataKey = ko.utils.domData.nextKey(),
function disposeOldComputedAndStoreNewOne(element, newComputed) { disposeOldComputedAndStoreNewOne = (element, newComputed) => {
var oldComputed = ko.utils.domData.get(element, templateComputedDomDataKey); var oldComputed = ko.utils.domData.get(element, templateComputedDomDataKey);
oldComputed?.['dispose']?.(); oldComputed?.['dispose']?.();
ko.utils.domData.set(element, templateComputedDomDataKey, (newComputed && (!newComputed.isActive || newComputed.isActive())) ? newComputed : undefined); ko.utils.domData.set(element, templateComputedDomDataKey, (newComputed && (!newComputed.isActive || newComputed.isActive())) ? newComputed : undefined);
} },
cleanContainerDomDataKey = ko.utils.domData.nextKey();
var cleanContainerDomDataKey = ko.utils.domData.nextKey();
ko.bindingHandlers['template'] = { ko.bindingHandlers['template'] = {
'init': (element, valueAccessor) => { 'init': (element, valueAccessor) => {
// Support anonymous templates // Support anonymous templates
@ -239,8 +240,7 @@
if ('foreach' in options) { if ('foreach' in options) {
// Render once for each data point (treating data set as empty if shouldDisplay==false) // Render once for each data point (treating data set as empty if shouldDisplay==false)
var dataArray = (shouldDisplay && options['foreach']) || []; templateComputed = renderTemplateForEach(template, (shouldDisplay && options['foreach']) || [], options, element, bindingContext);
templateComputed = ko.renderTemplateForEach(template, dataArray, options, element, bindingContext);
} else if (!shouldDisplay) { } else if (!shouldDisplay) {
ko.virtualElements.emptyNode(element); ko.virtualElements.emptyNode(element);
} else { } else {