devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
333 lines (282 loc) • 8.47 kB
JavaScript
"use strict";
var Class = require("../core/class"),
abstract = Class.abstract,
EventsMixin = require("../core/events_mixin"),
each = require("../core/utils/iterator").each,
errorsModule = require("./errors"),
dataUtils = require("./utils"),
compileGetter = require("../core/utils/data").compileGetter,
storeHelper = require("./store_helper"),
queryByOptions = storeHelper.queryByOptions,
Deferred = require("../core/utils/deferred").Deferred,
storeImpl = {};
/**
* @name Store
* @publicName Store
* @type object
* @inherits EventsMixin
* @hidden
* @module data/abstract_store
* @export default
*/
var Store = Class.inherit({
ctor: function ctor(options) {
var that = this;
options = options || {};
each([
/**
* @name StoreOptions.onLoaded
* @publicName onLoaded
* @type function
* @type_function_param1 result:Array<any>
* @action
*/
"onLoaded",
/**
* @name StoreOptions.onLoading
* @publicName onLoading
* @type function
* @type_function_param1 loadOptions:LoadOptions
* @action
*/
"onLoading",
/**
* @name StoreOptions.onInserted
* @publicName onInserted
* @type function
* @type_function_param1 values:object
* @type_function_param2 key:object|string|number
* @action
*/
"onInserted",
/**
* @name StoreOptions.onInserting
* @publicName onInserting
* @type function
* @type_function_param1 values:object
* @action
*/
"onInserting",
/**
* @name StoreOptions.onUpdated
* @publicName onUpdated
* @type function
* @type_function_param1 key:object|string|number
* @type_function_param2 values:object
* @action
*/
"onUpdated",
/**
* @name StoreOptions.onUpdating
* @publicName onUpdating
* @type function
* @type_function_param1 key:object|string|number
* @type_function_param2 values:object
* @action
*/
"onUpdating",
/**
* @name StoreOptions.onRemoved
* @publicName onRemoved
* @type function
* @type_function_param1 key:object|string|number
* @action
*/
"onRemoved",
/**
* @name StoreOptions.onRemoving
* @publicName onRemoving
* @type function
* @type_function_param1 key:object|string|number
* @action
*/
"onRemoving",
/**
* @name StoreOptions.onModified
* @publicName onModified
* @type function
* @action
*/
"onModified",
/**
* @name StoreOptions.onModifying
* @publicName onModifying
* @type function
* @action
*/
"onModifying"], function (_, optionName) {
if (optionName in options) {
that.on(optionName.slice(2).toLowerCase(), options[optionName]);
}
});
/**
* @name StoreOptions.key
* @publicName key
* @type string|Array<string>
*/
this._key = options.key;
/**
* @name StoreOptions.errorHandler
* @publicName errorHandler
* @type function
*/
this._errorHandler = options.errorHandler;
this._useDefaultSearch = true;
},
_customLoadOptions: function _customLoadOptions() {
return null;
},
/**
* @name StoreMethods.key
* @publicName key()
* @return any
*/
key: function key() {
return this._key;
},
/**
* @name StoreMethods.keyOf
* @publicName keyOf(obj)
* @param1 obj:object
* @return any
*/
keyOf: function keyOf(obj) {
if (!this._keyGetter) {
this._keyGetter = compileGetter(this.key());
}
return this._keyGetter(obj);
},
_requireKey: function _requireKey() {
if (!this.key()) {
throw errorsModule.errors.Error("E4005");
}
},
/**
* @name StoreMethods.load
* @publicName load()
* @return Promise<any>
*/
/**
* @name StoreMethods.load
* @publicName load(options)
* @param1 options:LoadOptions
* @return Promise<any>
*/
load: function load(options) {
var that = this;
options = options || {};
this.fireEvent("loading", [options]);
return this._withLock(this._loadImpl(options)).done(function (result) {
that.fireEvent("loaded", [result, options]);
});
},
_loadImpl: function _loadImpl(options) {
return queryByOptions(this.createQuery(options), options).enumerate();
},
_withLock: function _withLock(task) {
var result = new Deferred();
task.done(function () {
var that = this,
args = arguments;
dataUtils.processRequestResultLock.promise().done(function () {
result.resolveWith(that, args);
});
}).fail(function () {
result.rejectWith(this, arguments);
});
return result;
},
createQuery: abstract,
/**
* @name StoreMethods.totalCount
* @publicName totalCount(options)
* @param1 obj:object
* @param1_field1 filter:object
* @param1_field2 group:object
* @return Promise<number>
*/
totalCount: function totalCount(options) {
return this._totalCountImpl(options);
},
_totalCountImpl: function _totalCountImpl(options) {
return queryByOptions(this.createQuery(options), options, true).count();
},
/**
* @name StoreMethods.byKey
* @publicName byKey(key)
* @param1 key:object|string|number
* @return Promise<any>
*/
byKey: function byKey(key, extraOptions) {
return this._addFailHandlers(this._withLock(this._byKeyImpl(key, extraOptions)));
},
_byKeyImpl: abstract,
/**
* @name StoreMethods.insert
* @publicName insert(values)
* @param1 values:object
* @return Promise<any>
*/
insert: function insert(values) {
var that = this;
that.fireEvent("modifying");
that.fireEvent("inserting", [values]);
return that._addFailHandlers(that._insertImpl(values).done(function (callbackValues, callbackKey) {
that.fireEvent("inserted", [callbackValues, callbackKey]);
that.fireEvent("modified");
}));
},
_insertImpl: abstract,
/**
* @name StoreMethods.update
* @publicName update(key, values)
* @param1 key:object|string|number
* @param2 values:object
* @return Promise<any>
*/
update: function update(key, values) {
var that = this;
that.fireEvent("modifying");
that.fireEvent("updating", [key, values]);
return that._addFailHandlers(that._updateImpl(key, values).done(function (callbackKey, callbackValues) {
that.fireEvent("updated", [callbackKey, callbackValues]);
that.fireEvent("modified");
}));
},
_updateImpl: abstract,
/**
* @name StoreMethods.remove
* @publicName remove(key)
* @param1 key:object|string|number
* @return Promise<void>
*/
remove: function remove(key) {
var that = this;
that.fireEvent("modifying");
that.fireEvent("removing", [key]);
return that._addFailHandlers(that._removeImpl(key).done(function (callbackKey) {
that.fireEvent("removed", [callbackKey]);
that.fireEvent("modified");
}));
},
_removeImpl: abstract,
_addFailHandlers: function _addFailHandlers(deferred) {
return deferred.fail(this._errorHandler).fail(errorsModule._errorHandler);
}
}).include(EventsMixin);
Store.create = function (alias, options) {
if (!(alias in storeImpl)) {
throw errorsModule.errors.Error("E4020", alias);
}
return new storeImpl[alias](options);
};
Store.inherit = function (inheritor) {
return function (members, alias) {
var type = inheritor.apply(this, [members]);
if (alias) {
storeImpl[alias] = type;
}
return type;
};
}(Store.inherit);
module.exports = Store;