]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - data/DiffStore.js
22b84a6cd1c339992d570dc77fd503859421f1c5
[proxmox-widget-toolkit.git] / data / DiffStore.js
1 /*
2 * The DiffStore is a in-memory store acting as proxy between a real store
3 * instance and a component.
4 * Its purpose is to redisplay the component *only* if the data has been changed
5 * inside the real store, to avoid the annoying visual flickering of using
6 * the real store directly.
7 *
8 * Implementation:
9 * The DiffStore monitors via mon() the 'load' events sent by the real store.
10 * On each 'load' event, the DiffStore compares its own content with the target
11 * store (call to cond_add_item()) and then fires a 'refresh' event.
12 * The 'refresh' event will automatically trigger a view refresh on the component
13 * who binds to this store.
14 */
15
16 /* Config properties:
17 * rstore: the realstore which will autorefresh its content from the API
18 * Only works if rstore has a model and use 'idProperty'
19 * sortAfterUpdate: sort the diffstore before rendering the view
20 */
21 Ext.define('Proxmox.data.DiffStore', {
22 extend: 'Ext.data.Store',
23 alias: 'store.diff',
24
25 sortAfterUpdate: false,
26
27 constructor: function(config) {
28 var me = this;
29
30 config = config || {};
31
32 if (!config.rstore) {
33 throw "no rstore specified";
34 }
35
36 if (!config.rstore.model) {
37 throw "no rstore model specified";
38 }
39
40 var rstore = config.rstore;
41
42 Ext.apply(config, {
43 model: rstore.model,
44 proxy: { type: 'memory' }
45 });
46
47 me.callParent([config]);
48
49 var first_load = true;
50
51 var cond_add_item = function(data, id) {
52 var olditem = me.getById(id);
53 if (olditem) {
54 olditem.beginEdit();
55 Ext.Array.each(me.model.prototype.fields, function(field) {
56 if (olditem.data[field.name] !== data[field.name]) {
57 olditem.set(field.name, data[field.name]);
58 }
59 });
60 olditem.endEdit(true);
61 olditem.commit();
62 } else {
63 var newrec = Ext.create(me.model, data);
64 var pos = (me.appendAtStart && !first_load) ? 0 : me.data.length;
65 me.insert(pos, newrec);
66 }
67 };
68
69 var loadFn = function(s, records, success) {
70
71 if (!success) {
72 return;
73 }
74
75 me.suspendEvents();
76
77 // getSource returns null if data is not filtered
78 // if it is filtered it returns all records
79 var allItems = me.getData().getSource() || me.getData();
80
81 // remove vanished items
82 allItems.each(function(olditem) {
83 var item = rstore.getById(olditem.getId());
84 if (!item) {
85 me.remove(olditem);
86 }
87 });
88
89 rstore.each(function(item) {
90 cond_add_item(item.data, item.getId());
91 });
92
93 me.filter();
94
95 if (me.sortAfterUpdate) {
96 me.sort();
97 }
98
99 first_load = false;
100
101 me.resumeEvents();
102 me.fireEvent('refresh', me);
103 me.fireEvent('datachanged', me);
104 };
105
106 if (rstore.isLoaded()) {
107 // if store is already loaded,
108 // insert items instantly
109 loadFn(rstore, [], true);
110 }
111
112 me.mon(rstore, 'load', loadFn);
113 }
114 });