【问题标题】:ES6 invoke class method by string valueES6 通过字符串值调用类方法
【发布时间】:2017-09-11 10:15:06
【问题描述】:

我(我正在尝试使用通用方法来解析 dom 元素并将事件监听器附加到它们。

所以我添加了一个html5数据属性来指定触发事件时应该调用的方法。

我正在寻找的是一种通过她的字符串值调用类内部方法的方法:

static addEvent(element, trigger, action)
{
    element.on(trigger, action);
}

其中element是附加eventListener的dom元素,trigger是监听器的类型,action是我们应该在这个类中调用的方法(这里我要调用toggleFullscreen)。

有没有办法做到这一点?

编辑:需要避免eval解决方案,我用this[action]做了一个测试,但这不是例外结果。

这是我的代码

dom 元素:

<div class="interface">
    <span class="home_common-fullscreen action fa fa-desktop" data-action="toggleFullscreen" aria-hidden="true"></span>
</div>

javascript函数:

class Interface {
    constructor() {
        this.domElements = jQuery(".interface");

        this.attachAction();
    }

    attachAction()
    {
        let fullScreenButtonElement = this.domElements.find(".action");
        if(fullScreenButtonElement !== undefined)
        {
            if(Array.isArray(fullScreenButtonElement))
            {
                jQuery(fullScreenButtonElement).each(function()
                {
                    Interface.parseAction(this);
                });
            }
            else
            {
                Interface.parseAction(fullScreenButtonElement);
            }
        }
    }

    static parseAction(element)
    {
        let action = element.attr("data-action");
        if(action === undefined)
        {
            throw new InterfaceError("Trying to parse action element without defined data-action attribut");
        }

        let trigger = typeof element.attr("data-trigger") !== 'undefined' ? element.attr("data-trigger") : "click";

        try
        {
            Interface.addEvent(element, trigger, action);
        }
        catch(err)
        {
            console.log(action + "not found in Interface")
        }
    }

    static addEvent(element, trigger, action)
    {
        element.on(trigger, action);
    }

    toggleFullscreen()
    {
        alert("foo");
    }
}

JSFiddle

【问题讨论】:

  • 你在哪里实例化Interface?您在哪里尝试使用括号表示法?它应该工作

标签: javascript jquery ecmascript-6


【解决方案1】:
class Interface {
    // This method is a property of the class itself
    static addEvent(element,trigger,action) {
        element.on(trigger,Interface[action]);
    }

    // May need to be static if you don't plan on creating objects
    static toggleFullscreen() {
        console.log("It Works");
    }
}

// Or the Event Handler could be in another object
class EventHandlers {

    // It'd be accessed with EventHandlers["toggleFullscreen"];
    static toggleFullscreen() {

    }
}

// Or make it a global function
// Which would be accessed with window["toggleFullscreen"];
function toggleFullscreen() {

}

【讨论】:

  • 不,如果您不打算创建对象,则不应使用static。您根本不应该使用class
  • 我不认为使用类本质上是一个问题,尽管我认为大多数开发人员在这种情况下更愿意使用闭包/模块模式。
  • 但这条评论是解决方案的重点。和这里一样,在这个例子中使用一个类可能没用,但在实际代码中,这个类所做的不仅仅是使用 3 个静态方法。通过说他指出我可能需要重新考虑使用 addEvent 作为静态方法,而不是在接口实例化对象上使用它。
【解决方案2】:

你需要这样的东西吗:

class XClass {
  f2() {
    console.log("Message from f2");
  }

  f4() {
    eval("this.f2()");
  }
}

但我认为静态不适用于这种方法。

【讨论】:

  • 如果可能的话,我想避免评估
  • 由于一些安全问题,我认为使用 just 条件会更好。假设你实现了你所需要的,那么就可以通过改变“data”属性的值来调用“any”方法。因此,我认为 if (data=="blabla") attach(blabla) 会是更好的选择。
  • 你说得对,如果我能随心所欲地处理,这将是我最后的选择。但这里我展示了一个带有 dom 值的示例,但最终目的是将函数名称作为回调附加到从服务器接收的 json 中。
  • 你不必担心,有一种方法可以只用一个字符串来访问方法或属性。
  • 是的,我知道在 javascript
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多