1 |
efrain |
1 |
YUI.add('recordset-base', function (Y, NAME) {
|
|
|
2 |
|
|
|
3 |
/**
|
|
|
4 |
* Provides a wrapper around a standard javascript object. Can be inserted into a Recordset instance.
|
|
|
5 |
*
|
|
|
6 |
* @class Record
|
|
|
7 |
*/
|
|
|
8 |
var Record = Y.Base.create('record', Y.Base, [], {
|
|
|
9 |
_setId: function() {
|
|
|
10 |
return Y.guid();
|
|
|
11 |
},
|
|
|
12 |
|
|
|
13 |
initializer: function() {
|
|
|
14 |
},
|
|
|
15 |
|
|
|
16 |
destructor: function() {
|
|
|
17 |
},
|
|
|
18 |
|
|
|
19 |
/**
|
|
|
20 |
* Retrieve a particular (or all) values from the object
|
|
|
21 |
*
|
|
|
22 |
* @param field {string} (optional) The key to retrieve the value from. If not supplied, the entire object is returned.
|
|
|
23 |
* @method getValue
|
|
|
24 |
* @public
|
|
|
25 |
*/
|
|
|
26 |
getValue: function(field) {
|
|
|
27 |
if (field === undefined) {
|
|
|
28 |
return this.get("data");
|
|
|
29 |
}
|
|
|
30 |
else {
|
|
|
31 |
return this.get("data")[field];
|
|
|
32 |
}
|
|
|
33 |
return null;
|
|
|
34 |
}
|
|
|
35 |
},
|
|
|
36 |
{
|
|
|
37 |
ATTRS: {
|
|
|
38 |
|
|
|
39 |
/**
|
|
|
40 |
* @description Unique ID of the record instance
|
|
|
41 |
* @attribute id
|
|
|
42 |
* @type string
|
|
|
43 |
*/
|
|
|
44 |
id: {
|
|
|
45 |
valueFn: "_setId"
|
|
|
46 |
},
|
|
|
47 |
|
|
|
48 |
/**
|
|
|
49 |
* @description The object stored within the record instance
|
|
|
50 |
* @attribute data
|
|
|
51 |
* @type object
|
|
|
52 |
*/
|
|
|
53 |
data: {
|
|
|
54 |
value: null
|
|
|
55 |
}
|
|
|
56 |
}
|
|
|
57 |
});
|
|
|
58 |
|
|
|
59 |
Y.Record = Record;
|
|
|
60 |
/**
|
|
|
61 |
The Recordset utility provides a standard way for dealing with
|
|
|
62 |
a collection of similar objects.
|
|
|
63 |
@module recordset
|
|
|
64 |
@main recordset
|
|
|
65 |
@submodule recordset-base
|
|
|
66 |
**/
|
|
|
67 |
|
|
|
68 |
|
|
|
69 |
var ArrayList = Y.ArrayList,
|
|
|
70 |
Lang = Y.Lang,
|
|
|
71 |
|
|
|
72 |
/**
|
|
|
73 |
The Recordset utility provides a standard way for dealing with
|
|
|
74 |
a collection of similar objects.
|
|
|
75 |
|
|
|
76 |
Provides the base Recordset implementation, which can be extended to add
|
|
|
77 |
additional functionality, such as custom indexing. sorting, and filtering.
|
|
|
78 |
|
|
|
79 |
@class Recordset
|
|
|
80 |
@extends Base
|
|
|
81 |
@uses ArrayList
|
|
|
82 |
@param config {Object} Configuration object with initial attribute values
|
|
|
83 |
@constructor
|
|
|
84 |
**/
|
|
|
85 |
Recordset = Y.Base.create('recordset', Y.Base, [], {
|
|
|
86 |
|
|
|
87 |
|
|
|
88 |
/**
|
|
|
89 |
* Publish default functions for events. Create the initial hash table.
|
|
|
90 |
*
|
|
|
91 |
* @method initializer
|
|
|
92 |
* @protected
|
|
|
93 |
*/
|
|
|
94 |
initializer: function() {
|
|
|
95 |
// The reason the conditional is needed is because of two scenarios:
|
|
|
96 |
// 1. Instantiating new Y.Recordset() will not go into the setter of "records", and so it is necessary to create this._items in the initializer.
|
|
|
97 |
// 2. Instantiating new Y.Recordset({records: [{...}]}) will call the setter of "records" and create this._items. In this case, we don't want that to be overwritten by [].
|
|
|
98 |
if (!this._items) {
|
|
|
99 |
this._items = [];
|
|
|
100 |
}
|
|
|
101 |
|
|
|
102 |
//set up event listener to fire events when recordset is modified in anyway
|
|
|
103 |
this.publish({
|
|
|
104 |
/**
|
|
|
105 |
* <p>At least one record is being added. Additional properties of
|
|
|
106 |
* the event are:</p>
|
|
|
107 |
* <dl>
|
|
|
108 |
* <dt>added</dt>
|
|
|
109 |
* <dd>Array of new records to be added</dd>
|
|
|
110 |
* <dt>index</dt>
|
|
|
111 |
* <dd>The insertion index in the Recordset's internal
|
|
|
112 |
* array</dd>
|
|
|
113 |
* </dl>
|
|
|
114 |
*
|
|
|
115 |
* <p>Preventing this event will cause the new records NOT to be
|
|
|
116 |
* added to the Recordset's internal collection.</p>
|
|
|
117 |
*
|
|
|
118 |
* @event add
|
|
|
119 |
* @preventable _defAddFn
|
|
|
120 |
*/
|
|
|
121 |
add: { defaultFn: this._defAddFn },
|
|
|
122 |
|
|
|
123 |
/**
|
|
|
124 |
* <p>At least one record is being removed. Additional properties of
|
|
|
125 |
* the event are:</p>
|
|
|
126 |
* <dl>
|
|
|
127 |
* <dt>removed</dt>
|
|
|
128 |
* <dd>Array of records to be removed</dd>
|
|
|
129 |
* <dt>range</dt>
|
|
|
130 |
* <dd>Number of records to be removed</dd>
|
|
|
131 |
* <dt>index</dt>
|
|
|
132 |
* <dd>The starting index in the Recordset's internal
|
|
|
133 |
* array from which to remove records</dd>
|
|
|
134 |
* </dl>
|
|
|
135 |
*
|
|
|
136 |
* <p>Preventing this event will cause the records NOT to be
|
|
|
137 |
* removed from the Recordset's internal collection.</p>
|
|
|
138 |
*
|
|
|
139 |
* @event remove
|
|
|
140 |
* @preventable _defRemoveFn
|
|
|
141 |
*/
|
|
|
142 |
remove: { defaultFn: this._defRemoveFn },
|
|
|
143 |
|
|
|
144 |
/**
|
|
|
145 |
* The Recordset is being flushed of all records.
|
|
|
146 |
*
|
|
|
147 |
* @event empty
|
|
|
148 |
* @preventable _defEmptyFn
|
|
|
149 |
*/
|
|
|
150 |
empty: { defaultFn: this._defEmptyFn },
|
|
|
151 |
|
|
|
152 |
/**
|
|
|
153 |
* <p>At least one record is being updated. Additional properties of
|
|
|
154 |
* the event are:</p>
|
|
|
155 |
* <dl>
|
|
|
156 |
* <dt>updated</dt>
|
|
|
157 |
* <dd>Array of records with updated values</dd>
|
|
|
158 |
* <dt>overwritten</dt>
|
|
|
159 |
* <dd>Array of current records that will be replaced</dd>
|
|
|
160 |
* <dt>index</dt>
|
|
|
161 |
* <dd>The starting index in the Recordset's internal
|
|
|
162 |
* array from which to update will apply</dd>
|
|
|
163 |
* </dl>
|
|
|
164 |
*
|
|
|
165 |
* <p>Preventing this event will cause the records NOT to be
|
|
|
166 |
* updated in the Recordset's internal collection.</p>
|
|
|
167 |
*
|
|
|
168 |
* @event update
|
|
|
169 |
* @preventable _defUpdateFn
|
|
|
170 |
*/
|
|
|
171 |
update: { defaultFn: this._defUpdateFn }
|
|
|
172 |
});
|
|
|
173 |
|
|
|
174 |
this._buildHashTable(this.get('key'));
|
|
|
175 |
|
|
|
176 |
this.after([
|
|
|
177 |
'recordsChange',
|
|
|
178 |
'add',
|
|
|
179 |
'remove',
|
|
|
180 |
'update',
|
|
|
181 |
'empty'], this._updateHash);
|
|
|
182 |
},
|
|
|
183 |
|
|
|
184 |
/**
|
|
|
185 |
* Returns the record with particular ID or index
|
|
|
186 |
*
|
|
|
187 |
* @method getRecord
|
|
|
188 |
* @param i {String, Number} The ID of the record if a string, or the index if a number.
|
|
|
189 |
* @return {Record} A Y.Record instance
|
|
|
190 |
*/
|
|
|
191 |
getRecord: function(i) {
|
|
|
192 |
|
|
|
193 |
if (Lang.isString(i)) {
|
|
|
194 |
return this.get('table')[i];
|
|
|
195 |
}
|
|
|
196 |
else if (Lang.isNumber(i)) {
|
|
|
197 |
return this._items[i];
|
|
|
198 |
}
|
|
|
199 |
return null;
|
|
|
200 |
},
|
|
|
201 |
|
|
|
202 |
|
|
|
203 |
/**
|
|
|
204 |
* Returns the record at a particular index
|
|
|
205 |
*
|
|
|
206 |
* @method getRecordByIndex
|
|
|
207 |
* @param i {Number} Index at which the required record resides
|
|
|
208 |
* @return {Record} A Y.Record instance
|
|
|
209 |
*/
|
|
|
210 |
getRecordByIndex: function(i) {
|
|
|
211 |
return this._items[i];
|
|
|
212 |
},
|
|
|
213 |
|
|
|
214 |
/**
|
|
|
215 |
* Returns a range of records beginning at particular index
|
|
|
216 |
*
|
|
|
217 |
* @method getRecordsByIndex
|
|
|
218 |
* @param index {Number} Index at which the required record resides
|
|
|
219 |
* @param range {Number} (Optional) Number of records to retrieve. The default is 1
|
|
|
220 |
* @return {Array} An array of Y.Record instances
|
|
|
221 |
*/
|
|
|
222 |
getRecordsByIndex: function(index, range) {
|
|
|
223 |
var i = 0,
|
|
|
224 |
returnedRecords = [];
|
|
|
225 |
//Range cannot take on negative values
|
|
|
226 |
range = (Lang.isNumber(range) && (range > 0)) ? range: 1;
|
|
|
227 |
|
|
|
228 |
for (; i < range; i++) {
|
|
|
229 |
returnedRecords.push(this._items[index + i]);
|
|
|
230 |
}
|
|
|
231 |
return returnedRecords;
|
|
|
232 |
},
|
|
|
233 |
|
|
|
234 |
/**
|
|
|
235 |
* Returns the length of the recordset
|
|
|
236 |
*
|
|
|
237 |
* @method getLength
|
|
|
238 |
* @return {Number} Number of records in the recordset
|
|
|
239 |
*/
|
|
|
240 |
getLength: function() {
|
|
|
241 |
return this.size();
|
|
|
242 |
},
|
|
|
243 |
|
|
|
244 |
/**
|
|
|
245 |
Gets an array of values for a data _key_ in the set's records. If no _key_
|
|
|
246 |
is supplied, the returned array will contain the full data object for each
|
|
|
247 |
record.
|
|
|
248 |
|
|
|
249 |
@method getValuesByKey
|
|
|
250 |
@param {String} [key] Data property to get from all records
|
|
|
251 |
@return {Array} An array of values for the given _key_ if supplied.
|
|
|
252 |
Otherwise, an array of each record's data hash.
|
|
|
253 |
**/
|
|
|
254 |
getValuesByKey: function(key) {
|
|
|
255 |
var i = 0,
|
|
|
256 |
len = this._items.length,
|
|
|
257 |
retVals = [];
|
|
|
258 |
for (; i < len; i++) {
|
|
|
259 |
retVals.push(this._items[i].getValue(key));
|
|
|
260 |
}
|
|
|
261 |
return retVals;
|
|
|
262 |
},
|
|
|
263 |
|
|
|
264 |
|
|
|
265 |
/**
|
|
|
266 |
* Adds one or more Records to the RecordSet at the given index. If index is null, then adds the Records to the end of the RecordSet.
|
|
|
267 |
*
|
|
|
268 |
* @method add
|
|
|
269 |
* @param {Record|Object|Array} oData A Y.Record instance, An object literal of data or an array of object literals
|
|
|
270 |
* @param [index] {Number} [index] Index at which to add the record(s)
|
|
|
271 |
* @return {Recordset} The updated recordset instance
|
|
|
272 |
*/
|
|
|
273 |
add: function(oData, index) {
|
|
|
274 |
|
|
|
275 |
var newRecords = [],
|
|
|
276 |
idx,
|
|
|
277 |
i = 0;
|
|
|
278 |
|
|
|
279 |
idx = (Lang.isNumber(index) && (index > -1)) ? index: this._items.length;
|
|
|
280 |
|
|
|
281 |
//Passing in array of object literals for oData
|
|
|
282 |
if (Lang.isArray(oData)) {
|
|
|
283 |
for (; i < oData.length; i++) {
|
|
|
284 |
newRecords[i] = this._changeToRecord(oData[i]);
|
|
|
285 |
}
|
|
|
286 |
} else if (Lang.isObject(oData)) {
|
|
|
287 |
newRecords[0] = this._changeToRecord(oData);
|
|
|
288 |
}
|
|
|
289 |
|
|
|
290 |
this.fire('add', {
|
|
|
291 |
added: newRecords,
|
|
|
292 |
index: idx
|
|
|
293 |
});
|
|
|
294 |
return this;
|
|
|
295 |
},
|
|
|
296 |
|
|
|
297 |
/**
|
|
|
298 |
Removes one or more Records to the RecordSet at the given index. If index
|
|
|
299 |
is null, then removes a single Record from the end of the RecordSet.
|
|
|
300 |
|
|
|
301 |
@method remove
|
|
|
302 |
@param {Number} [index] Index at which to remove the record(s) from
|
|
|
303 |
@param {Number} [range] Number of records to remove (including the one
|
|
|
304 |
at the index)
|
|
|
305 |
@return {Recordset} The updated recordset instance
|
|
|
306 |
**/
|
|
|
307 |
remove: function(index, range) {
|
|
|
308 |
var remRecords = [];
|
|
|
309 |
|
|
|
310 |
//Default is to only remove the last record - the length is always 1 greater than the last index
|
|
|
311 |
index = (index > -1) ? index: (this._items.length - 1);
|
|
|
312 |
range = (range > 0) ? range: 1;
|
|
|
313 |
|
|
|
314 |
remRecords = this._items.slice(index, (index + range));
|
|
|
315 |
this.fire('remove', {
|
|
|
316 |
removed: remRecords,
|
|
|
317 |
range: range,
|
|
|
318 |
index: index
|
|
|
319 |
});
|
|
|
320 |
//this._recordRemoved(remRecords, index);
|
|
|
321 |
//return ({data: remRecords, index:index});
|
|
|
322 |
return this;
|
|
|
323 |
},
|
|
|
324 |
|
|
|
325 |
/**
|
|
|
326 |
* Empties the recordset
|
|
|
327 |
*
|
|
|
328 |
* @method empty
|
|
|
329 |
* @return {Recordset} The updated recordset instance
|
|
|
330 |
*/
|
|
|
331 |
empty: function() {
|
|
|
332 |
this.fire('empty', {});
|
|
|
333 |
return this;
|
|
|
334 |
},
|
|
|
335 |
|
|
|
336 |
/**
|
|
|
337 |
Updates the recordset with the new records passed in. Overwrites existing
|
|
|
338 |
records when updating the index with the new records.
|
|
|
339 |
|
|
|
340 |
@method update
|
|
|
341 |
@param {Record|Object|Array} data A Y.Record instance, An object literal of
|
|
|
342 |
data or an array of object literals
|
|
|
343 |
@param {Number} [index] The index to start updating from.
|
|
|
344 |
@return {Recordset} The updated recordset instance
|
|
|
345 |
**/
|
|
|
346 |
update: function(data, index) {
|
|
|
347 |
var rec,
|
|
|
348 |
arr,
|
|
|
349 |
i = 0;
|
|
|
350 |
|
|
|
351 |
// Whatever is passed in, we are changing it to an array so that it can
|
|
|
352 |
// be easily iterated in the _defUpdateFn method
|
|
|
353 |
arr = (!(Lang.isArray(data))) ? [data] : data;
|
|
|
354 |
rec = this._items.slice(index, index + arr.length);
|
|
|
355 |
|
|
|
356 |
for (; i < arr.length; i++) {
|
|
|
357 |
arr[i] = this._changeToRecord(arr[i]);
|
|
|
358 |
}
|
|
|
359 |
|
|
|
360 |
this.fire('update', {
|
|
|
361 |
updated: arr,
|
|
|
362 |
overwritten: rec,
|
|
|
363 |
index: index
|
|
|
364 |
});
|
|
|
365 |
|
|
|
366 |
return this;
|
|
|
367 |
},
|
|
|
368 |
|
|
|
369 |
/**
|
|
|
370 |
* Default behavior for the "add" event. Adds Record instances starting from
|
|
|
371 |
* the index specified in `e.index`.
|
|
|
372 |
*
|
|
|
373 |
* @method _defAddFn
|
|
|
374 |
* @param {EventFacade} e The add event
|
|
|
375 |
* @private
|
|
|
376 |
*/
|
|
|
377 |
_defAddFn: function(e) {
|
|
|
378 |
this._items.splice.apply(this._items, [e.index, 0].concat(e.added));
|
|
|
379 |
},
|
|
|
380 |
|
|
|
381 |
/**
|
|
|
382 |
* Default behavior for the "remove" event. Removes Records from the
|
|
|
383 |
* internal array starting from `e.index`. By default, it will remove one
|
|
|
384 |
* Record. But if `e.range` is set, it will remove that many Records.
|
|
|
385 |
*
|
|
|
386 |
* @method _defRemoveFn
|
|
|
387 |
* @param {EventFacade} e The remove event
|
|
|
388 |
* @private
|
|
|
389 |
*/
|
|
|
390 |
_defRemoveFn: function(e) {
|
|
|
391 |
this._items.splice(e.index, e.range || 1);
|
|
|
392 |
},
|
|
|
393 |
|
|
|
394 |
/**
|
|
|
395 |
* Default behavior for the "update" event. Sets Record instances for each
|
|
|
396 |
* item in `e.updated` at indexes starting from `e.index`.
|
|
|
397 |
*
|
|
|
398 |
* @method _defUpdateFn
|
|
|
399 |
* @param {EventFacade} e The update event
|
|
|
400 |
* @private
|
|
|
401 |
*/
|
|
|
402 |
_defUpdateFn: function(e) {
|
|
|
403 |
for (var i = 0; i < e.updated.length; i++) {
|
|
|
404 |
this._items[e.index + i] = this._changeToRecord(e.updated[i]);
|
|
|
405 |
}
|
|
|
406 |
},
|
|
|
407 |
|
|
|
408 |
/**
|
|
|
409 |
* Default behavior for the "empty" event. Clears the internal array of
|
|
|
410 |
* Records.
|
|
|
411 |
*
|
|
|
412 |
* @method _defEmptyFn
|
|
|
413 |
* @param {EventFacade} e The empty event
|
|
|
414 |
* @private
|
|
|
415 |
*/
|
|
|
416 |
_defEmptyFn: function(e) {
|
|
|
417 |
this._items = [];
|
|
|
418 |
Y.log('empty fired');
|
|
|
419 |
},
|
|
|
420 |
|
|
|
421 |
/**
|
|
|
422 |
Updates the internal hash table.
|
|
|
423 |
|
|
|
424 |
@method _defUpdateHash
|
|
|
425 |
@param {EventFacade} e Event triggering the hash table update
|
|
|
426 |
@private
|
|
|
427 |
**/
|
|
|
428 |
_updateHash: function (e) {
|
|
|
429 |
var handler = "_hash",
|
|
|
430 |
type = e.type.replace(/.*:/,''),
|
|
|
431 |
newHash;
|
|
|
432 |
|
|
|
433 |
// _hashAdd, _hashRemove, _hashEmpty, etc
|
|
|
434 |
// Not a switch or else if setup to allow for external expansion.
|
|
|
435 |
handler += type.charAt(0).toUpperCase() + type.slice(1);
|
|
|
436 |
|
|
|
437 |
newHash = this[handler] &&
|
|
|
438 |
this[handler](this.get('table'), this.get('key'), e);
|
|
|
439 |
|
|
|
440 |
if (newHash) {
|
|
|
441 |
this.set('table', newHash);
|
|
|
442 |
}
|
|
|
443 |
},
|
|
|
444 |
|
|
|
445 |
/**
|
|
|
446 |
Regenerates the hash table from the current internal array of Records.
|
|
|
447 |
|
|
|
448 |
@method _hashRecordsChange
|
|
|
449 |
@param {Object} hash The hash map before replacement
|
|
|
450 |
@param {String} key The key by which to add items to the hash
|
|
|
451 |
@param {Object} e The event or object containing the items to be added.
|
|
|
452 |
Items are expected to be stored in an array assigned to
|
|
|
453 |
the `added` property.
|
|
|
454 |
@return {Object} The updated hash map
|
|
|
455 |
@private
|
|
|
456 |
**/
|
|
|
457 |
_hashRecordsChange: function (hash, key, e) {
|
|
|
458 |
return this._buildHashTable(key);
|
|
|
459 |
},
|
|
|
460 |
|
|
|
461 |
/**
|
|
|
462 |
Builds a hash table from the current internal array of Records.
|
|
|
463 |
|
|
|
464 |
@method _buildHashTable
|
|
|
465 |
@param {String} key The Record key to hash the items by
|
|
|
466 |
@return {Object} A new hash map of Records keyed by each Records' key
|
|
|
467 |
@private
|
|
|
468 |
**/
|
|
|
469 |
_buildHashTable: function (key) {
|
|
|
470 |
return this._hashAdd({}, key, { added: this._items });
|
|
|
471 |
},
|
|
|
472 |
|
|
|
473 |
/**
|
|
|
474 |
Adds items to the hash table. Items are the values, and the keys are the
|
|
|
475 |
values of the item's attribute named in the `key` parameter.
|
|
|
476 |
|
|
|
477 |
@method _hashAdd
|
|
|
478 |
@param {Object} hash The hash map before adding items
|
|
|
479 |
@param {String} key The key by which to add the items to the hash
|
|
|
480 |
@param {Object} e The event or object containing the items to be added.
|
|
|
481 |
Items are expected to be stored in an array assigned to
|
|
|
482 |
the `added` property.
|
|
|
483 |
@return {Object} The updated hash map
|
|
|
484 |
@private
|
|
|
485 |
**/
|
|
|
486 |
_hashAdd: function(hash, key, e) {
|
|
|
487 |
var items = e.added,
|
|
|
488 |
i, len;
|
|
|
489 |
|
|
|
490 |
for (i = 0, len = e.added.length; i < len; ++i) {
|
|
|
491 |
hash[items[i].get(key)] = items[i];
|
|
|
492 |
}
|
|
|
493 |
|
|
|
494 |
return hash;
|
|
|
495 |
},
|
|
|
496 |
|
|
|
497 |
/**
|
|
|
498 |
Removes items from the hash table.
|
|
|
499 |
|
|
|
500 |
@method _hashRemove
|
|
|
501 |
@param {Object} hash The hash map before removing items
|
|
|
502 |
@param {String} key The key by which to remove the items from the hash
|
|
|
503 |
@param {Object} e The event or object containing the items to be removed.
|
|
|
504 |
Items are expected to be stored in an array assigned to
|
|
|
505 |
the `removed` property.
|
|
|
506 |
@return {Object} The updated hash map
|
|
|
507 |
@private
|
|
|
508 |
**/
|
|
|
509 |
_hashRemove: function(hash, key, e) {
|
|
|
510 |
for (var i = e.removed.length - 1; i >= 0; --i) {
|
|
|
511 |
delete hash[e.removed[i].get(key)];
|
|
|
512 |
}
|
|
|
513 |
|
|
|
514 |
return hash;
|
|
|
515 |
},
|
|
|
516 |
|
|
|
517 |
/**
|
|
|
518 |
Updates items in the hash table.
|
|
|
519 |
|
|
|
520 |
@method _hashUpdate
|
|
|
521 |
@param {Object} hash The hash map before updating items
|
|
|
522 |
@param {String} key The key by which to update the items to the hash
|
|
|
523 |
@param {Object} e The event or object containing the items to be updated.
|
|
|
524 |
Items are expected to be stored in an array assigned to
|
|
|
525 |
the `updated` property. Optionally, items can be
|
|
|
526 |
identified for being overwritten by including them in an
|
|
|
527 |
array assigned to the `overwritten` property.
|
|
|
528 |
@return {Object} The updated hash map
|
|
|
529 |
@private
|
|
|
530 |
**/
|
|
|
531 |
_hashUpdate: function (hash, key, e) {
|
|
|
532 |
if (e.overwritten && e.overwritten.length) {
|
|
|
533 |
hash = this._hashRemove(hash, key, { removed: e.overwritten });
|
|
|
534 |
}
|
|
|
535 |
|
|
|
536 |
return this._hashAdd(hash, key, { added: e.updated });
|
|
|
537 |
},
|
|
|
538 |
|
|
|
539 |
/**
|
|
|
540 |
Clears the hash table.
|
|
|
541 |
|
|
|
542 |
@method _hashEmpty
|
|
|
543 |
@param {Object} hash The hash map before adding items
|
|
|
544 |
@param {String} key The key by which to remove the items from the hash
|
|
|
545 |
@param {Object} e The event or object containing the items to be removed.
|
|
|
546 |
Items are expected to be stored in an array assigned to
|
|
|
547 |
the `removed` property.
|
|
|
548 |
@return {Object} An empty hash
|
|
|
549 |
@private
|
|
|
550 |
**/
|
|
|
551 |
_hashEmpty: function() {
|
|
|
552 |
return {};
|
|
|
553 |
},
|
|
|
554 |
|
|
|
555 |
/**
|
|
|
556 |
* Sets up the hashtable with all the records currently in the recordset
|
|
|
557 |
*
|
|
|
558 |
* @method _initHashTable
|
|
|
559 |
* @private
|
|
|
560 |
*/
|
|
|
561 |
_initHashTable: function() {
|
|
|
562 |
return this._hashAdd({}, this.get('key'), { added: this._items || [] });
|
|
|
563 |
},
|
|
|
564 |
|
|
|
565 |
/**
|
|
|
566 |
* Helper method - it takes an object bag and converts it to a Y.Record
|
|
|
567 |
*
|
|
|
568 |
* @method _changeToRecord
|
|
|
569 |
* @param obj {Object|Record} Any objet literal or Y.Record instance
|
|
|
570 |
* @return {Record} A Record instance.
|
|
|
571 |
* @private
|
|
|
572 |
*/
|
|
|
573 |
_changeToRecord: function(obj) {
|
|
|
574 |
return (obj instanceof Y.Record) ? obj : new Y.Record({ data: obj });
|
|
|
575 |
},
|
|
|
576 |
|
|
|
577 |
/**
|
|
|
578 |
Ensures the value being set is an array of Record instances. If array items
|
|
|
579 |
are raw object data, they are turned into Records.
|
|
|
580 |
|
|
|
581 |
@method _setRecords
|
|
|
582 |
@param {Record[]|Object[]} items The Records or data Objects to store as
|
|
|
583 |
Records.
|
|
|
584 |
@return {Record[]}
|
|
|
585 |
**/
|
|
|
586 |
_setRecords: function (items) {
|
|
|
587 |
if (!Y.Lang.isArray(items)) {
|
|
|
588 |
return Y.Attribute.INVALID_VALUE;
|
|
|
589 |
}
|
|
|
590 |
|
|
|
591 |
var records = [],
|
|
|
592 |
i, len;
|
|
|
593 |
|
|
|
594 |
// FIXME: This should use the flyweight pattern if possible
|
|
|
595 |
for (i = 0, len = items.length; i < len; ++i) {
|
|
|
596 |
records[i] = this._changeToRecord(items[i]);
|
|
|
597 |
}
|
|
|
598 |
|
|
|
599 |
return (this._items = records);
|
|
|
600 |
}
|
|
|
601 |
}, {
|
|
|
602 |
ATTRS: {
|
|
|
603 |
|
|
|
604 |
/**
|
|
|
605 |
* An array of Records that the Recordset is storing. Passing an array
|
|
|
606 |
* of raw record data is also accepted. The data for each item will be
|
|
|
607 |
* wrapped in a Record instance.
|
|
|
608 |
*
|
|
|
609 |
* @attribute records
|
|
|
610 |
* @type {Record[]}
|
|
|
611 |
*/
|
|
|
612 |
records: {
|
|
|
613 |
// TODO: necessary? valueFn?
|
|
|
614 |
lazyAdd: false,
|
|
|
615 |
getter: function() {
|
|
|
616 |
// give them a copy, not the internal object
|
|
|
617 |
return Y.Array(this._items);
|
|
|
618 |
},
|
|
|
619 |
setter: "_setRecords"
|
|
|
620 |
},
|
|
|
621 |
|
|
|
622 |
/**
|
|
|
623 |
A hash table where the ID of the record is the key, and the record
|
|
|
624 |
instance is the value.
|
|
|
625 |
|
|
|
626 |
@attribute table
|
|
|
627 |
@type object
|
|
|
628 |
**/
|
|
|
629 |
table: {
|
|
|
630 |
valueFn: '_initHashTable'
|
|
|
631 |
},
|
|
|
632 |
|
|
|
633 |
/**
|
|
|
634 |
The ID to use as the key in the hash table.
|
|
|
635 |
|
|
|
636 |
@attribute key
|
|
|
637 |
@type string
|
|
|
638 |
**/
|
|
|
639 |
key: {
|
|
|
640 |
value: 'id',
|
|
|
641 |
readOnly: true
|
|
|
642 |
}
|
|
|
643 |
|
|
|
644 |
}
|
|
|
645 |
});
|
|
|
646 |
Y.augment(Recordset, ArrayList);
|
|
|
647 |
Y.Recordset = Recordset;
|
|
|
648 |
|
|
|
649 |
|
|
|
650 |
|
|
|
651 |
}, '3.18.1', {"requires": ["base", "arraylist"]});
|