]> git.proxmox.com Git - proxmox-widget-toolkit.git/blame - data/DiffStore.js
data/DiffStore: add autoDestroyRstore flag
[proxmox-widget-toolkit.git] / data / DiffStore.js
CommitLineData
0bb29d35
DM
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 */
21Ext.define('Proxmox.data.DiffStore', {
22 extend: 'Ext.data.Store',
23 alias: 'store.diff',
24
25 sortAfterUpdate: false,
13fc756d 26
65277f6a
DC
27 // if set to true, destroy rstore on destruction
28 autoDestroyRstore: false,
29
30 onDestroy: function() {
31 let me = this;
32 if (me.autoDestroyRstore) {
33 if (Ext.isFunction(me.rstore.destroy)) {
34 me.rstore.destroy();
35 }
36 delete me.rstore;
37 }
38 me.callParent();
39 },
40
0bb29d35
DM
41 constructor: function(config) {
42 var me = this;
43
44 config = config || {};
45
46 if (!config.rstore) {
47 throw "no rstore specified";
48 }
49
50 if (!config.rstore.model) {
51 throw "no rstore model specified";
52 }
53
54 var rstore = config.rstore;
55
56 Ext.apply(config, {
57 model: rstore.model,
58 proxy: { type: 'memory' }
59 });
60
61 me.callParent([config]);
62
65277f6a
DC
63 me.rstore = rstore;
64
0bb29d35
DM
65 var first_load = true;
66
67 var cond_add_item = function(data, id) {
68 var olditem = me.getById(id);
69 if (olditem) {
70 olditem.beginEdit();
71 Ext.Array.each(me.model.prototype.fields, function(field) {
72 if (olditem.data[field.name] !== data[field.name]) {
73 olditem.set(field.name, data[field.name]);
74 }
75 });
76 olditem.endEdit(true);
13fc756d 77 olditem.commit();
0bb29d35
DM
78 } else {
79 var newrec = Ext.create(me.model, data);
80 var pos = (me.appendAtStart && !first_load) ? 0 : me.data.length;
81 me.insert(pos, newrec);
82 }
83 };
84
85 var loadFn = function(s, records, success) {
86
87 if (!success) {
88 return;
89 }
90
91 me.suspendEvents();
92
93 // getSource returns null if data is not filtered
94 // if it is filtered it returns all records
95 var allItems = me.getData().getSource() || me.getData();
96
97 // remove vanished items
98 allItems.each(function(olditem) {
65277f6a 99 var item = me.rstore.getById(olditem.getId());
0bb29d35
DM
100 if (!item) {
101 me.remove(olditem);
102 }
103 });
104
65277f6a 105 me.rstore.each(function(item) {
0bb29d35
DM
106 cond_add_item(item.data, item.getId());
107 });
108
109 me.filter();
110
111 if (me.sortAfterUpdate) {
112 me.sort();
113 }
114
115 first_load = false;
116
117 me.resumeEvents();
118 me.fireEvent('refresh', me);
119 me.fireEvent('datachanged', me);
120 };
121
65277f6a 122 if (me.rstore.isLoaded()) {
0bb29d35
DM
123 // if store is already loaded,
124 // insert items instantly
65277f6a 125 loadFn(me.rstore, [], true);
0bb29d35
DM
126 }
127
65277f6a 128 me.mon(me.rstore, 'load', loadFn);
0bb29d35
DM
129 }
130});