aurelia-templating-resources
Version:
A standard set of behaviors, converters and other resources for use with the Aurelia templating library.
109 lines (98 loc) • 2.92 kB
text/typescript
import {createFullOverrideContext, updateOverrideContexts} from './repeat-utilities';
/**
* A strategy for repeating a template over a Set.
*/
export class SetRepeatStrategy {
/**
* Gets a Set observer.
* @param items The items to be observed.
*/
getCollectionObserver(observerLocator, items) {
return observerLocator.getSetObserver(items);
}
/**
* Process the provided Set entries.
* @param items The entries to process.
*/
instanceChanged(repeat, items) {
let removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
if (removePromise instanceof Promise) {
removePromise.then(() => this._standardProcessItems(repeat, items));
return;
}
this._standardProcessItems(repeat, items);
}
/**
* @internal
*/
_standardProcessItems(repeat, items) {
let index = 0;
let overrideContext;
items.forEach(value => {
overrideContext = createFullOverrideContext(repeat, value, index, items.size);
repeat.addView(overrideContext.bindingContext, overrideContext);
++index;
});
}
/**
* Handle changes in a Set collection.
* @param repeat The repeat instance.
* @param set The underlying Set collection.
* @param records The change records.
*/
instanceMutated(repeat, set, records) {
let value;
let i;
let ii;
let overrideContext;
let removeIndex;
let record;
let rmPromises = [];
let viewOrPromise;
for (i = 0, ii = records.length; i < ii; ++i) {
record = records[i];
value = record.value;
switch (record.type) {
case 'add':
let size = Math.max(set.size - 1, 0);
overrideContext = createFullOverrideContext(repeat, value, size, set.size);
repeat.insertView(size, overrideContext.bindingContext, overrideContext);
break;
case 'delete':
removeIndex = this._getViewIndexByValue(repeat, value);
viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);
if (viewOrPromise instanceof Promise) {
rmPromises.push(viewOrPromise);
}
break;
case 'clear':
repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
break;
default:
continue;
}
}
if (rmPromises.length > 0) {
Promise.all(rmPromises).then(() => {
updateOverrideContexts(repeat.views(), 0);
});
} else {
updateOverrideContexts(repeat.views(), 0);
}
}
/**
* @internal
*/
_getViewIndexByValue(repeat, value) {
let i;
let ii;
let child;
for (i = 0, ii = repeat.viewCount(); i < ii; ++i) {
child = repeat.view(i);
if (child.bindingContext[repeat.local] === value) {
return i;
}
}
return undefined;
}
}