namespace drunk { import util = drunk . util ; import Parser = drunk . Parser ; import Filter = drunk . Filter ; import Watcher = drunk . Watcher ; import observable = drunk . observable ; import EventEmitter = drunk . EventEmitter ; var global = util . global ; export interface IModel extends observable . IObservableObject { [ key ] : any ; } /**
     * Decorator for ViewModel#$computed
     */ export function computed ( target , property , descriptor ) { let getter ; let setter ; let proxies ; if ( descriptor . get ) { getter = descriptor . get ; proxies = Parser . getProxyProperties ( descriptor . get ) ; } if ( descriptor . set ) { setter = descriptor . set ; } function computedGetterSetter ( ) { if ( ! arguments . length ) { if ( getter ) { if ( proxies ) { proxies . forEach ( prop => this . $proxy ( prop ) ) ; } try { return getter . call ( this ) ; } catch ( e ) { } } } else if ( setter ) { try { setter . call ( this , arguments [ 0 ] ) ; } catch ( e ) { } } } descriptor . get = computedGetterSetter ; descriptor . set = computedGetterSetter ; descriptor . enumerable = true ; descriptor . configurable = true ; return descriptor ; } /**
     * ViewModel类， 实现数据与模板元素的绑定
     */ export class ViewModel extends EventEmitter { /**
         * 实例是否未被释放
         */ _isActived : boolean ; /**
         * 数据对象
         */ _model : IModel ; /**
         * 该实例下所有的绑定实例的列表
         */ _bindings : Binding [ ] ; /**
         * 该实例下所有的watcher实例表
         */ _watchers : { [ expression ] : Watcher ; } ; /** 代理的属性 */ _proxyProps : { [ property ] : boolean ; } ; /**
         * 过滤器方法,包含内置的
         */ $filter : { [ name ] : Filter . IFilter ; } ; /**
         * 事件处理方法集合
         */ handlers : { [ name ] : ( ... args : any [ ] ) => any ; } ; param model constructor ( model ? ) { super ( ) ; this . __init ( model ) ; } param model protected __init ( model ? ) { model = model || { } ; observable . create ( model ) ; Object . defineProperties ( this , { $filter : { value : Object . create ( Filter . filters ) , configurable : true , writable : true } , _model : { value : model , configurable : true , writable : true } , _bindings : { value : [ ] , configurable : true , writable : true } , _watchers : { value : { } , configurable : true , writable : true } , _proxyProps : { value : { } , configurable : true , writable : true } , _isActived : { value : true , configurable : true , writable : true } } ) ; Object . keys ( model ) . forEach ( ( property ) => { this . $proxy ( property ) ; } ) ; } param property $proxy ( property ) { if ( this . _proxyProps [ property ] || typeof this [ property ] === 'function' ) { return ; } var value = this [ property ] ; if ( value === undefined ) { value = this . _model [ property ] ; } if ( util . createProxy ( this , property , this . _model ) ) { this . _model . $set ( property , value ) ; } this . _proxyProps [ property ] = true ; } param expression param isInterpolate $eval ( expression , isInterpolate ? ) { var getter ; if ( isInterpolate ) { if ( ! Parser . hasInterpolation ( expression ) ) { return expression ; } getter = Parser . parseInterpolate ( expression ) ; } else { getter = Parser . parseGetter ( expression ) ; } return this . __execGetter ( getter , isInterpolate ) ; } param expression param value $setValue ( expression , value ) { var setter = Parser . parseSetter ( expression ) ; setter . call ( this , value ) ; } return $getModel ( ) { let model = { } ; Object . keys ( this . _proxyProps ) . forEach ( prop => model [ prop ] = this [ prop ] ) ; return util . extend ( model , util . deepClone ( this . _model ) ) ; } param expression return $watch ( expression , action , isDeepWatch ? , isImmediate ? ) { var key = Watcher . getNameOfKey ( expression , isDeepWatch ) ; var watcher ; watcher = this . _watchers [ key ] ; if ( ! watcher ) { watcher = this . _watchers [ key ] = new Watcher ( this , expression , isDeepWatch ) ; } var wrappedAction = ( newValue , oldValue ) => { action . call ( this , newValue , oldValue ) ; } ; watcher . addAction ( wrappedAction ) ; if ( isImmediate ) { wrappedAction ( watcher . value , undefined ) ; } return ( ) => { watcher . removeAction ( wrappedAction ) ; } ; } $computed ( property , descriptor ) ; $computed ( property , descriptor ) ; $computed ( property , descriptor ) { let observer = observable . create ( this . _model ) ; if ( typeof descriptor === 'function' ) { descriptor = { get : descriptor } ; } descriptor = computed ( this , property , descriptor ) ; Object . defineProperty ( this , property , descriptor ) ; this . _proxyProps [ property ] = true ; observer . $emit ( property ) ; } /**
         * 释放ViewModel实例的所有元素与数据的绑定,解除所有的代理属性,解除所有的视图与数据绑定,移除事件缓存,销毁所有的watcher
         */ $release ( ) { if ( ! this . _isActived ) { return ; } Object . keys ( this . _proxyProps ) . forEach ( property => { delete this [ property ] ; } ) ; Object . keys ( this . _watchers ) . forEach ( key => { if ( this . _watchers [ key ] ) { this . _watchers [ key ] . dispose ( ) ; } } ) ; this . _bindings . slice ( ) . forEach ( binding => { binding . $dispose ( ) ; } ) ; EventEmitter . cleanup ( this ) ; this . _model = this . _bindings = this . _watchers = this . _proxyProps = this . $filter = null ; this . _isActived = false ; } param handlerName return protected __getHandler ( handlerName ) { var handler = this [ handlerName ] ; var context = this ; if ( ! handler ) { if ( typeof global [ handlerName ] === 'function' ) { handler = global [ handlerName ] ; context = global ; } else { throw new Error ( handlerName + ": 没有找到该事件处理方法" ) ; } } return ( ... args ) => { handler . apply ( context , args ) ; } ; } param getter param isInterpolate param event param el protected __execGetter ( getter , isInterpolate ) { var value = getter . call ( this , null , null , util . global ) ; return Filter . pipeFor . apply ( null , [ value , getter . filters , this . $filter , isInterpolate , this ] ) ; } } }