UNPKG

base-domain

Version:

simple module to help build Domain-Driven Design

255 lines (182 loc) 4.78 kB
BaseModel = require './base-model' ###* list class of DDD pattern. @class BaseList @extends BaseModel @module base-domain ### class BaseList extends BaseModel ###* model name of the item @property itemModelName @static @protected @type String ### @itemModelName: '' ###* creates child class of BaseList @method getAnonymousClass @params {String} itemModelName @return {Function} child class of BaseList ### @getAnonymousClass: (itemModelName) -> class AnonymousList extends BaseList @itemModelName: itemModelName @isAnonymous: true return AnonymousList ###* ids: get ids of items @property ids @type Array @public ### Object.defineProperty @::, 'ids', get: -> return null if not @constructor.containsEntity() return (item.id for item in @items) ###* 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 ### constructor: (props = {}) -> # loaded and listeners are hidden properties _itemFactory = null Object.defineProperties @, items : value: [], enumerable: true loaded : value: false, writable: true listeners : value: [] itemFactory : get: -> _itemFactory ?= @getFacade().createFactory(@constructor.itemModelName, true) if props.items @setItems props.items if props.ids @setIds props.ids super(props) ###* set ids. @method setIds @param {Array(String|Number)} ids ### setIds: (ids = []) -> return if not @constructor.containsEntity() @loaded = false ItemRepository = @getFacade().getRepository(@constructor.itemModelName) repo = new ItemRepository() if ItemRepository.storeMasterTable and ItemRepository.loaded() subModels = (repo.getByIdSync(id) for id in ids) @setItems(subModels) else repo.query(where: id: inq: ids).then (subModels) => @setItems(subModels) return @ ###* set items @method setItems @param {Array} models ### setItems: (models = []) -> ItemClass = @getFacade().getModel @constructor.itemModelName @items.push item for item in models when item instanceof ItemClass @items.sort(@sort) @loaded = true @emitLoaded() return @ ###* returns item is Entity @method containsEntity @static @public @return {Boolean} ### @containsEntity: -> return @getFacade().getModel(@itemModelName).isEntity ###* sort items in constructor @method sort @protected ### sort: (modelA, modelB) -> if modelA.id > modelB.id then 1 else -1 ###* first item @method first @public ### first: -> if @items.length is 0 return null return @items[0] ###* last item @method last @public ### last: -> if @items.length is 0 return null return @items[@items.length - 1] ###* export models to Array @method toArray @public ### toArray: -> @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 ### toPlainObject: -> plain = super() if @constructor.containsEntity() plain.ids = @ids delete plain.items else plainItems = [] for item in @items if typeof item.toPlainObject is 'function' plainItems.push item.toPlainObject() else plainItems.push item plain.items = plainItems return plain ###* on addEventListeners for 'loaded' @method on @public ### on: (evtname, fn) -> return if evtname isnt 'loaded' if @loaded process.nextTick fn else if typeof fn is 'function' @listeners.push fn return ###* tell listeners emit loaded @method emitLoaded @private ### emitLoaded: -> while fn = @listeners.shift() process.nextTick fn return module.exports = BaseList