1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
import {EventEmitter} from 'events';
import _ from "lodash";
import utils from "../utils.js";
function SortByStoreOrder(elem) {
return this.store.index(elem.id);
}
var default_sort = SortByStoreOrder;
var default_filt = function (elem) {
return true;
};
export function StoreView(store, filt, sortfun) {
EventEmitter.call(this);
this.store = store;
this.add = this.add.bind(this);
this.update = this.update.bind(this);
this.remove = this.remove.bind(this);
this.recalculate = this.recalculate.bind(this);
this.store.addListener("add", this.add);
this.store.addListener("update", this.update);
this.store.addListener("remove", this.remove);
this.store.addListener("recalculate", this.recalculate);
this.recalculate(filt, sortfun);
}
_.extend(StoreView.prototype, EventEmitter.prototype, {
close: function () {
this.store.removeListener("add", this.add);
this.store.removeListener("update", this.update);
this.store.removeListener("remove", this.remove);
this.store.removeListener("recalculate", this.recalculate);
this.removeAllListeners();
},
recalculate: function (filt, sortfun) {
filt = filt || this.filt || default_filt;
sortfun = sortfun || this.sortfun || default_sort;
filt = filt.bind(this);
sortfun = sortfun.bind(this);
this.filt = filt;
this.sortfun = sortfun;
this.list = this.store.list.filter(filt);
this.list.sort(function (a, b) {
var akey = sortfun(a);
var bkey = sortfun(b);
if(akey < bkey){
return -1;
} else if(akey > bkey){
return 1;
} else {
return 0;
}
});
this.emit("recalculate");
},
indexOf: function (elem) {
return this.list.indexOf(elem, _.sortedIndexBy(this.list, elem, this.sortfun));
},
add: function (elem) {
if (this.filt(elem)) {
var idx = _.sortedIndexBy(this.list, elem, this.sortfun);
if (idx === this.list.length) { //happens often, .push is way faster.
this.list.push(elem);
} else {
this.list.splice(idx, 0, elem);
}
this.emit("add", elem, idx);
}
},
update: function (elem) {
var idx;
var i = this.list.length;
// Search from the back, we usually update the latest entries.
while (i--) {
if (this.list[i].id === elem.id) {
idx = i;
break;
}
}
if (idx === -1) { //not contained in list
this.add(elem);
} else if (!this.filt(elem)) {
this.remove(elem.id);
} else {
if (this.sortfun(this.list[idx]) !== this.sortfun(elem)) { //sortpos has changed
this.remove(this.list[idx]);
this.add(elem);
} else {
this.list[idx] = elem;
this.emit("update", elem, idx);
}
}
},
remove: function (elem_id) {
var idx = this.list.length;
while (idx--) {
if (this.list[idx].id === elem_id) {
this.list.splice(idx, 1);
this.emit("remove", elem_id, idx);
break;
}
}
}
});
|