UNPKG

base-domain

Version:

simple module to help build Domain-Driven Design

363 lines (286 loc) 6.9 kB
var BaseList, BaseModel, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; BaseModel = require('./base-model'); /** list class of DDD pattern. @class BaseList @extends BaseModel @module base-domain */ BaseList = (function(superClass) { extend(BaseList, superClass); /** model name of the item @property itemModelName @static @protected @type String */ BaseList.itemModelName = ''; /** creates child class of BaseList @method getAnonymousClass @params {String} itemModelName @return {Function} child class of BaseList */ BaseList.getAnonymousClass = function(itemModelName) { var AnonymousList; AnonymousList = (function(superClass1) { extend(AnonymousList, superClass1); function AnonymousList() { return AnonymousList.__super__.constructor.apply(this, arguments); } AnonymousList.itemModelName = itemModelName; AnonymousList.isAnonymous = true; return AnonymousList; })(BaseList); return AnonymousList; }; /** ids: get ids of items @property ids @type Array @public */ Object.defineProperty(BaseList.prototype, 'ids', { get: function() { var item; if (!this.constructor.containsEntity()) { return null; } return (function() { var i, len, ref, results; ref = this.items; results = []; for (i = 0, len = ref.length; i < len; i++) { item = ref[i]; results.push(item.id); } return results; }).call(this); } }); /** items: array of models @property items @type Array */ /** loaded: is data loaded or not @property loaded @type Boolean */ /** itemFactory: instance of factory which creates item models @property itemFactory @type BaseFactory */ /** @constructor */ function BaseList(props) { var _itemFactory; if (props == null) { props = {}; } _itemFactory = null; Object.defineProperties(this, { items: { value: [], enumerable: true }, loaded: { value: false, writable: true }, listeners: { value: [] }, itemFactory: { get: function() { return _itemFactory != null ? _itemFactory : _itemFactory = this.getFacade().createFactory(this.constructor.itemModelName, true); } } }); if (props.items) { this.setItems(props.items); } if (props.ids) { this.setIds(props.ids); } BaseList.__super__.constructor.call(this, props); } /** set ids. @method setIds @param {Array(String|Number)} ids */ BaseList.prototype.setIds = function(ids) { var ItemRepository, id, repo, subModels; if (ids == null) { ids = []; } if (!this.constructor.containsEntity()) { return; } this.loaded = false; ItemRepository = this.getFacade().getRepository(this.constructor.itemModelName); repo = new ItemRepository(); if (ItemRepository.storeMasterTable && ItemRepository.loaded()) { subModels = (function() { var i, len, results; results = []; for (i = 0, len = ids.length; i < len; i++) { id = ids[i]; results.push(repo.getByIdSync(id)); } return results; })(); this.setItems(subModels); } else { repo.query({ where: { id: { inq: ids } } }).then((function(_this) { return function(subModels) { return _this.setItems(subModels); }; })(this)); } return this; }; /** set items @method setItems @param {Array} models */ BaseList.prototype.setItems = function(models) { var ItemClass, i, item, len; if (models == null) { models = []; } ItemClass = this.getFacade().getModel(this.constructor.itemModelName); for (i = 0, len = models.length; i < len; i++) { item = models[i]; if (item instanceof ItemClass) { this.items.push(item); } } this.items.sort(this.sort); this.loaded = true; this.emitLoaded(); return this; }; /** returns item is Entity @method containsEntity @static @public @return {Boolean} */ BaseList.containsEntity = function() { return this.getFacade().getModel(this.itemModelName).isEntity; }; /** sort items in constructor @method sort @protected */ BaseList.prototype.sort = function(modelA, modelB) { if (modelA.id > modelB.id) { return 1; } else { return -1; } }; /** first item @method first @public */ BaseList.prototype.first = function() { if (this.items.length === 0) { return null; } return this.items[0]; }; /** last item @method last @public */ BaseList.prototype.last = function() { if (this.items.length === 0) { return null; } return this.items[this.items.length - 1]; }; /** export models to Array @method toArray @public */ BaseList.prototype.toArray = function() { return this.items.slice(); }; /** create plain list. if this list contains entities, returns their ids if this list contains non-entity models, returns their plain objects @method toPlainObject @return {Object} plainObject */ BaseList.prototype.toPlainObject = function() { var i, item, len, plain, plainItems, ref; plain = BaseList.__super__.toPlainObject.call(this); if (this.constructor.containsEntity()) { plain.ids = this.ids; delete plain.items; } else { plainItems = []; ref = this.items; for (i = 0, len = ref.length; i < len; i++) { item = ref[i]; if (typeof item.toPlainObject === 'function') { plainItems.push(item.toPlainObject()); } else { plainItems.push(item); } } plain.items = plainItems; } return plain; }; /** on addEventListeners for 'loaded' @method on @public */ BaseList.prototype.on = function(evtname, fn) { if (evtname !== 'loaded') { return; } if (this.loaded) { process.nextTick(fn); } else if (typeof fn === 'function') { this.listeners.push(fn); } }; /** tell listeners emit loaded @method emitLoaded @private */ BaseList.prototype.emitLoaded = function() { var fn; while (fn = this.listeners.shift()) { process.nextTick(fn); } }; return BaseList; })(BaseModel); module.exports = BaseList;