UNPKG

3.52 kBPlain TextView Raw
1import {createFullOverrideContext, updateOverrideContexts} from './repeat-utilities';
2
3/**
4 * A strategy for repeating a template over a Map.
5 */
6export class MapRepeatStrategy {
7 /**
8 * Gets a Map observer.
9 * @param items The items to be observed.
10 */
11 getCollectionObserver(observerLocator, items) {
12 return observerLocator.getMapObserver(items);
13 }
14
15 /**
16 * Process the provided Map entries.
17 * @param items The entries to process.
18 */
19 instanceChanged(repeat, items) {
20 let removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
21 if (removePromise instanceof Promise) {
22 removePromise.then(() => this._standardProcessItems(repeat, items));
23 return;
24 }
25 this._standardProcessItems(repeat, items);
26 }
27
28 /**
29 * @internal
30 */
31 _standardProcessItems(repeat, items) {
32 let index = 0;
33 let overrideContext;
34
35 items.forEach((value, key) => {
36 overrideContext = createFullOverrideContext(repeat, value, index, items.size, key);
37 repeat.addView(overrideContext.bindingContext, overrideContext);
38 ++index;
39 });
40 }
41
42 /**
43 * Handle changes in a Map collection.
44 * @param map The underlying Map collection.
45 * @param records The change records.
46 */
47 instanceMutated(repeat, map, records) {
48 let key;
49 let i;
50 let ii;
51 let overrideContext;
52 let removeIndex;
53 let addIndex;
54 let record;
55 let rmPromises = [];
56 let viewOrPromise;
57
58 for (i = 0, ii = records.length; i < ii; ++i) {
59 record = records[i];
60 key = record.key;
61 switch (record.type) {
62 case 'update':
63 removeIndex = this._getViewIndexByKey(repeat, key);
64 viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);
65 if (viewOrPromise instanceof Promise) {
66 rmPromises.push(viewOrPromise);
67 }
68 overrideContext = createFullOverrideContext(repeat, map.get(key), removeIndex, map.size, key);
69 repeat.insertView(removeIndex, overrideContext.bindingContext, overrideContext);
70 break;
71 case 'add':
72 addIndex = repeat.viewCount() <= map.size - 1 ? repeat.viewCount() : map.size - 1;
73 overrideContext = createFullOverrideContext(repeat, map.get(key), addIndex, map.size, key);
74 repeat.insertView(map.size - 1, overrideContext.bindingContext, overrideContext);
75 break;
76 case 'delete':
77 if (record.oldValue === undefined) { return; }
78 removeIndex = this._getViewIndexByKey(repeat, key);
79 viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);
80 if (viewOrPromise instanceof Promise) {
81 rmPromises.push(viewOrPromise);
82 }
83 break;
84 case 'clear':
85 repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
86 break;
87 default:
88 continue;
89 }
90 }
91
92 if (rmPromises.length > 0) {
93 Promise.all(rmPromises).then(() => {
94 updateOverrideContexts(repeat.views(), 0);
95 });
96 } else {
97 updateOverrideContexts(repeat.views(), 0);
98 }
99 }
100
101 /**
102 * @internal
103 */
104 _getViewIndexByKey(repeat, key) {
105 let i: number;
106 let ii: number;
107 let child;
108
109 for (i = 0, ii = repeat.viewCount(); i < ii; ++i) {
110 child = repeat.view(i);
111 if (child.bindingContext[repeat.key] === key) {
112 return i;
113 }
114 }
115
116 return undefined;
117 }
118}