import { Subject , Subscription } from 'rxjs' ; import { DataItem , FieldChangedEvent } from './data-item' ; export class ListChangedEvent { constructor ( public item , public event ) { } } export class ListAddedEvent { constructor ( public item ) { } } export class ListRemovedEvent { constructor ( public item ) { } } export class ListClearedEvent { constructor ( ) { } } export type DataItemListEvent = ListChangedEvent | ListAddedEvent | ListRemovedEvent | ListClearedEvent ; export class DataItemList { items : DataItem [ ] = [ ] ; changed = new Subject < DataItemListEvent > ( ) ; private itemChangedSubscriptions : Map < DataItem , Subscription > = new Map ( ) ; destroyed = false ; constructor ( items ? , callInitItems = true ) { if ( items && callInitItems ) this . initItems ( items ) ; } initItems ( items ? ) { this . clear ( ) ; items . forEach ( item => { if ( ! ( item instanceof DataItem ) ) throw new Error ( 'All items must have DataItem type.' ) ; this . _addItem ( item ) ; } ) ; } protected _addItem ( item ) { if ( ! this . items ) { this . items = [ ] ; } this . items . push ( item ) ; this . itemChangedSubscriptions . set ( item , item . __director__ . changed . subscribe ( ev => { this . changed . next ( new ListChangedEvent ( item , ev ) ) ; } ) ) ; } add ( ... items ) { items . forEach ( item => { this . _addItem ( item ) ; this . changed . next ( new ListAddedEvent ( item ) ) ; } ) ; } remove ( ... items ) { this . _remove ( items ) ; } protected _remove ( items , emitChanged = true ) { items . forEach ( item => { var pos = this . items . indexOf ( item ) ; if ( ! this . items || ! this . items . length || pos == - 1 ) throw new Error ( 'The DataItem is not in this list.' ) ; this . items . splice ( pos , 1 ) ; this . itemChangedSubscriptions . get ( item ) . unsubscribe ( ) ; this . itemChangedSubscriptions . delete ( item ) ; if ( emitChanged ) this . changed . next ( new ListRemovedEvent ( item ) ) ; } ) ; } clear ( ) { if ( ! this . items || ! this . items . length ) return ; this . _remove ( this . items , false ) ; this . changed . next ( new ListClearedEvent ( ) ) ; } toJSON ( ) { return this . items ; } }