/**
 * 转换后的可以监控数组
 * 除了有常规数组的所有方法外还添加了几个工具方法，并在某些修改自身的方法调用后对新数据进行处理和
 * 发送数据更新的通知。
 */ namespace drunk . observable { import util = drunk . util ; /**
     * 可监控数组的声明
     */ export interface IObservableArray < T > extends Array < T > { __observer__ ? : Observer ; $setAt ? ( index , value ) : void ; $removeAt ? < T > ( index ) : T ; $removeItem ? ( item ) : void ; $removeAllItem ? ( item ) : void ; $removeAll ? ( ) : void ; } /**
     * 数组转换成observable后指向的原型对象
     */ export var ObservableArrayPrototype = Object . create ( Array . prototype ) ; param array param index param value export function $setAt < T > ( array , index , value ) { if ( index > array . length ) { array . length = index + 1 ; } array . splice ( index , 1 , value ) ; } param array param index export function $removeAt < T > ( array , index ) { let result ; if ( index > - 1 && index < array . length ) { result = Array . prototype . splice . call ( array , index , 1 ) [ 0 ] ; notify ( array ) ; } return result ; } param array param value export function $removeItem < T > ( array , value ) { util . removeArrayItem ( array , value ) ; } param array param value export function $removeAllItem < T > ( array , value ) { var matchedIndexList = [ ] ; var step = 0 ; array . forEach ( ( item , index ) => { if ( value === item ) { matchedIndexList . push ( index - step ++ ) ; } } ) ; if ( matchedIndexList . length ) { matchedIndexList . forEach ( index => { array . splice ( index , 1 ) ; } ) ; notify ( array ) ; } } /**
     * 删除所有数组元素
     */ export function $removeAll < T > ( array ) { if ( array . length ) { array . length = 0 ; notify ( array ) ; } } Object . defineProperties ( ObservableArrayPrototype , { param index param value $setAt : { value : function setObservableArrayItem ( index , value ) { $setAt ( this , index , value ) ; } } , param index $removeAt : { value : function removeObservalbeArrayByIndex ( index ) { return $removeAt ( this , index ) ; } } , param value $removeItem : { value : function removeObservableArrayItem ( value ) { return $removeItem ( this , value ) ; } } , param value $removeAllItem : { value : function removeAllObservableArrayItem ( value ) { return $removeAllItem ( this , value ) ; } } , method $removeAll : { value : function ( ) { return $removeAll ( this ) ; } } , pop : { value : function pop ( ) { let result = Array . prototype . pop . call ( this ) ; notify ( this ) ; return result ; } } , shift : { value : function shift ( ) { let result = Array . prototype . shift . call ( this ) ; notify ( this ) ; return result ; } } , push : { value : function push ( ... args ) { let result = Array . prototype . push . apply ( this , args ) ; args . forEach ( create ) ; notify ( this ) ; return result ; } } , unshift : { value : function unshift ( ... args ) { let result = Array . prototype . unshift . apply ( this , args ) ; args . forEach ( create ) ; notify ( this ) ; return result ; } } , splice : { value : function splice ( ... args ) { let result = Array . prototype . splice . apply ( this , args ) ; args . slice ( 2 ) . forEach ( create ) ; notify ( this ) ; return result ; } } , sort : { value : function sort ( callback ? ) { let result = Array . prototype . sort . call ( this , callback ) ; notify ( this ) ; return result ; } } , reverse : { value : function reverse ( ) { let result = Array . prototype . reverse . call ( this ) ; notify ( this ) ; return result ; } } } ) ; }