/
FluxStore.js
188 lines (161 loc) · 3.63 KB
/
FluxStore.js
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
(function (enyo, scope) {
var kind = enyo.kind,
EventEmitter = enyo.EventEmitter,
StateSupport = enyo.StateSupport;
function update(node, src) {
var key, val;
if (!(node && src)) return;
// avoid iterating over null/undefined
for (key in src) {
// avoid looking this value up over and over
val = src[key];
// don't clear current values if one wasn't returned
if (val != null) {
// if there isn't a value already we short-circuit the object test for efficiency
if (!node[key] || !enyo.isObject(val)) node[key] = val;
else update(node[key], val);
}
}
return node;
}
/**
*
*
* @class enyo.FluxStore
* @mixes enyo.EventEmitter
* @extends enyo.Object
* @public
*/
kind(
/** @lends enyo.FluxStore.prototype */ {
name: 'enyo.FluxStore',
/**
* @private
*/
kind: enyo.Object,
/**
* @private
*/
data: {},
/**
* @name enyo.FluxStore.id
*
* How a store is identitified to the Flux Dispatcher
* This ID is used for subscribing to a store's
* state notification change
*
* @public
* @type {Number}
*
*/
id: -1,
mixins: [EventEmitter, StateSupport],
/**
* @name enyo.FluxStore.source
*
* The source that this FluxStore should use to fetch new
* data sets.
*
* @public
* @type {String}
*
*/
source: '',
published: {
/**
* @name enyo.FluxStore.MergeRoot
*
* When a source sends data to the store,
* should the data root have the new data
* merged, otherwise it will replace.
*
* @public
* @type {Boolean}
* @default true
*
*/
MergeRoot: true
},
/**
* @private
*/
constructor: enyo.inherit(function(sup){
return function(){
sup.apply(this, arguments);
if(enyo.FluxDispatcher) {
//subscribe the store to the dispatcher
this.id = enyo.FluxDispatcher.subscribe();
}
};
}),
/**
* @name enyo.FluxStore.add
*
* Adds data to the store, is called from the store's fetch
*
* @param [data] - Object that has the data to be added to store.
* @param {enyo.FluxStore~ActionOptions} [opts] - Optional configuration options.
* @private
*/
add: function (data, opts) {
if(this.MergeRoot) {
update(this.data, data);
return;
}
this.data = data;
},
/**
* @name enyo.FluxStore.reset
*
* Clears the store's data
*
* @public
*/
reset: function () {
this.data = {};
},
/**
* @name enyo.FluxStore.fetch
*
* Fetches the data from a [Source]{@link enyo.Source}
*
* @param {enyo.FluxStore~ActionOptions} [opts] - Optional configuration options.
* @public
*/
fetch: function(opts) {
opts = opts || {};
opts.success = opts.success || this.success.bind(this);
opts.error = opts.error || this.error.bind(this);
enyo.Source.execute('fetch', this, opts);
},
/**
* @name enyo.FluxStore.success
*
* Success callback is called when the [Source]{@link enyo.Source} is successful
*
* @param {enyo.Source} [source] - The source that iniated the fetch.
* @param {enyo.Source~Results} [res] - The result of the fetch.
* @private
*/
success: function(source, res) {
//when the result comes back from
//the fetch add it to the store
this.add(res);
//tell the dispatcher to notify all subscribers
//that the payload has been updated for this store
enyo.FluxDispatcher.notify(this.id, this.data);
},
/**
* @name enyo.FluxStore.error
*
* Error callback is called when the [Source]{@link enyo.Source} has failed
*
* @param {enyo.Source~Results} [res] - The result of the fetch.
* @private
*/
error: function(res) {
//error occured during fetch
//todo: warn user
}
});
})(enyo, this);