import * as EventEmitter from "eventemitter3" ; import filter from "lodash-es/filter" ; interface ISubscription { emitter : EventEmitter ; event : string ; callback : ( ... args : any [ ] ) => void ; } /**
 * Model is a base for Model-Like objects.
 *
 * Model provides some event-model and general attribute management
 * facilities. Model basically provides getter, setter methods for
 * attributes and an event subscription system to notify of attribute
 * changes or other custom events. Model is used mainly by Components
 * to model component options and thus allow editors to treat each
 * component as a Data Model object to drive user interface.
 */ export default abstract class Model extends EventEmitter { private subscriptions : ISubscription [ ] = [ ] ; param key public abstract get ( key ) ; param key public abstract toJSON ( key ) ; param key param value param options public set ( key , value , options ? ) { let success ; if ( typeof ( key ) === "string" ) { options = options || { } ; const silent = typeof ( options . silent ) === "undefined" ? true : false ; success = this . setAttribute ( key , value , options ) ; if ( success && ! silent ) { this . emit ( "change:" + key , this , value , options ) ; this . emit ( "change" , this , options ) ; } } else { options = value || { } ; const silent = typeof ( options . silent ) === "undefined" ? true : false ; const keyValueMap = key ; success = false ; for ( key in keyValueMap ) { if ( this . setAttribute ( key , keyValueMap [ key ] , options ) ) { success = true ; if ( ! silent ) { this . emit ( "change:" + key , this , keyValueMap [ key ] , options ) ; } } } if ( success && ! silent ) { this . emit ( "change" , this , options ) ; } } return success ; } param emitter param event param callback protected listenTo ( emitter , event , callback ) { emitter . addListener ( event , callback ) ; this . subscriptions . push ( { emitter , event , callback } ) ; } param emitter param event param callback protected stopListening ( emitter ? , event ? , callback ? ) { const subFilter = { } ; if ( emitter ) { subFilter . emitter = emitter ; } if ( event ) { subFilter . event = event ; } if ( emitter ) { subFilter . callback = callback ; } const subs = filter ( this . subscriptions , subFilter ) ; subs . forEach ( ( sub ) => { sub . emitter . removeListener ( sub . event , sub . callback ) ; } ) ; } param key param value param options protected abstract setAttribute ( key , value , options ) ; }