En una clase hay varios métodos static y el método a llamar se decidirá en el tiempo de ejecución. ¿Cómo podría llamar a este método dinámicamente?

export default class channel {

    // METHOD THAT WILL DYNAMICALLY CALL OTHER STATIC METHODS
    private static methodMap = {
        'channel-create' : 'create',
        'channel-user-count' : 'userCount',
        'channel-close' : 'close'
    };

    public static do(commandType:string,params: any) {
        if(channel.methodMap.hasOwnProperty(commandType)) {
            // GET NAME OF THE METHOD
            let method = channel.methodMap[commandType];
            // CALL METHOD ON THE FLY
            //return channel.call(method,params);
            // channel.userCount(params);
        }
    }
    /**
     * Adds channel to available channel list
     */
    private static create(channelName:string) {

    }

    /**
     * Returns count of users in the channel
     */
    private static userCount(channelName:string) {

    }

}
0
Suhail Gupta 16 feb. 2017 a las 21:08

3 respuestas

La mejor respuesta

Almacene las funciones directamente en el mapa:

type MethodMap = { [name: string]: (any) => void };

private static methodMap: MethodMap = {
    'channel-create': Channel.create,
    'channel-user-count': Channel.userCount,
    'channel-close': Channel.close,
};

public static do(commandType: string, params: any) {
    if (channel.methodMap.hasOwnProperty(commandType)) {
        const method = channel.methodMap[commandType];
        method(params);
    }
}
4
Ry- 17 feb. 2017 a las 00:28

Para agregar a la respuesta de @HardikModha, también puede hacer que el compilador verifique commandType con los posibles valores:

public static do(commandType: keyof typeof Channel.methodMap, params: any) {
    if(Channel.methodMap.hasOwnProperty(commandType)) {
        let method = Channel.methodMap[commandType];

        return Channel[method](params);
    }
}
...

Channel.do('channel-create', 'MyChannel'); // fine
Channel.do('channel-created', 'MyChannel'); // error

(código en el área de juegos)

0
Nitzan Tomer 16 feb. 2017 a las 22:54

Puede invocar dinámicamente un método utilizando Classname['methodName'](param). Como en su caso, puede invocar el método create como Channel['create']('MyChannel')

Aquí está el ejemplo de trabajo: Juego de escritura mecanografiado

class Channel {

    private static methodMap = {
        'channel-create' : 'create',
        'channel-user-count' : 'userCount',
        'channel-close' : 'close'
    };

    private static create(channelName:string) {
        alert('Called with ' + channelName);
    }

    private static userCount(channelName:string) {
        alert('Usercount called with ' + channelName);
    }

    public static do(commandType: string, params: any) {
        if(Channel.methodMap.hasOwnProperty(commandType)) {
            let method = Channel.methodMap[commandType];

            return Channel[method](params);
        }
    }
}

Channel.do('channel-create', 'MyChannel');
Channel.do('channel-user-count', 1000);

Editar : Aunque el enfoque anterior funciona, como @Ryan mencionó en su respuesta, proporcionar funciones directamente en el mapa es mucho más limpio.

private static methodMap: MethodMap = {
    'channel-create': Channel.create,
    'channel-user-count': Channel.userCount,
    'channel-close': Channel.close,
};
5
Hardik Modha 17 feb. 2017 a las 06:08