base-domain
Version:
simple module to help build Domain-Driven Design
301 lines (220 loc) • 5.86 kB
text/coffeescript
BaseModel = require './base-model'
###*
dictionary-structured data model
BaseDict
BaseModel
base-domain
###
class BaseDict extends BaseModel
###*
model name of the item
itemModelName
String
###
: ''
###*
get unique key from item
key
###
: (item) -> item.id
###*
creates child class of BaseDict
getAnonymousClass
{String} itemModelName
{Function} child class of BaseDict
###
: (itemModelName) ->
class AnonymousDict extends BaseDict
: itemModelName
: true
return AnonymousDict
###*
ids: get ids of items
ids
Array
###
Object.defineProperty @::, 'ids',
get: ->
return null if not .containsEntity()
return (item.id for key, item of )
###*
items: dictionary of keys - models
items
Objects
###
###*
loaded: is data loaded or not
loaded
Boolean
###
###*
itemFactory: instance of factory which creates item models
itemFactory
BaseFactory
###
###*
###
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 ?= .createFactory(.itemModelName, true)
if props.items
props.items
if props.ids
props.ids
super(props)
###*
check if the model has submodel of the given key or not
has
{String|Number} key
{Boolean}
###
has: (key) ->
[key]?
###*
check if the model contains the given submodel or not
contains
{BaseModel} item
{Boolean}
###
contains: (item) ->
key = .key item
sameKeyItem =
item is sameKeyItem
###*
return submodel of the given key
get
{String|Number} key
{BaseModel}
###
get: (key) ->
[key]
###*
add new submodel to item(s)
get
{BaseModel} item
###
add: (items...) ->
ItemClass = .getModel .itemModelName
for prevKey, item of items when item instanceof ItemClass
key = .key item
[key] = item
###*
remove submodel from items
both acceptable, keys and submodels
remove
{BaseModel|String|Number} item
###
remove: (args...) ->
ItemClass = .getModel .itemModelName
for arg in args
if arg instanceof ItemClass
key = .key(arg)
else
key = arg
delete [key]
return
###*
set ids.
setIds
{Array(String|Number)} ids
###
setIds: (ids = []) ->
return if not .containsEntity()
= false
ItemRepository = .getRepository(.itemModelName)
repo = new ItemRepository()
if ItemRepository.storeMasterTable and ItemRepository.loaded()
subModels = (repo.getByIdSync(id) for id in ids)
else
repo.query(where: id: inq: ids).then (subModels) =>
return @
###*
set items from dic object
update to new key
setItems
{Object|Array} models
###
setItems: (models = {}) ->
items = (item for prevKey, item of models)
items...
= true
return @
###*
returns item is Entity
containsEntity
{Boolean}
###
: ->
return .getModel().isEntity
###*
export models to Array
toArray
###
toArray: ->
(item for key, item of )
###*
create plain dict.
if this dict contains entities, returns their ids
if this dict contains non-entity models, returns their plain objects
toPlainObject
{Object} plainObject
###
toPlainObject: ->
plain = super()
if .containsEntity()
plain.ids =
delete plain.items
else
plainItems = []
for key, item of
if typeof item.toPlainObject is 'function'
plainItems[key] = item.toPlainObject()
else
plainItems[key] = item
plain.items = plainItems
return plain
###*
on addEventlisteners for 'loaded'
on
###
on: (evtname, fn) ->
return if evtname isnt 'loaded'
if
process.nextTick fn
else if typeof fn is 'function'
.push fn
return
###*
tell listeners emit loaded
emitLoaded
###
emitLoaded: ->
while fn = .shift()
process.nextTick fn
return
module.exports = BaseDict