【问题标题】:Define a method to call when event occurs in module定义在模块中发生事件时调用的方法
【发布时间】:2018-06-10 10:59:59
【问题描述】:

我确定以前有人问过这个问题,但我只能找到不同问题的答案。

我想要做的这个要点是,当用户单击按钮时,我有一个模块调用另一个模块中的函数。但这是非常紧密的耦合,并导致各种维护问题,在一个模块中更改代码意味着我必须在多个其他模块中更改它。

我想做的只是定义一个函数或属性,然后在用户单击按钮后调用它。

当前代码示例:

// MyModule.js
class MyClass() {
    constructor(options) {
        // Set options
        // ...
    }

    // Called when button is clicked via event listener
    onClick() {
        // Update Module State
        // ...

        AnotherModule.someFunction(clickInfo);
    }
}

但这一点都不灵活,意味着模块不能单独存在。

我更喜欢这样的东西:

// MyModule.js
class MyClass() {
    constructor(options) {
        // Set options
        // ...

        this.clickCallback = null; // Function to be called
    }

    // Called when button is clicked via event listener
    onClick() {
        // Update Module State
        // ...

        this.onClickCallback(clickInfo);
    }

    // Called everytime user clicks
    onClickCallback(clickInfo) {
        this.clickCallback(clickInfo);
    }

    setClickCallback(customFunction) {
        this.clickCallback = customFunction;
    }
}

// SomeOtherFile.js
import myModule from './mymodule'

myModule.setClickCallback( (clickInfo) => { this.myFunction(clickInfo) } );

myFunction(data) {
    // Do stuff with click data
}

但这意味着我只能定义 1 个外部函数。如果在计算 clickInfo 后需要调用多个函数怎么办?
这至少是正确的想法吗?
我应该通过方法还是通过设置属性来设置clickCallback 函数?
我应该改用某种类型的自定义事件发射器/侦听器吗?

我想过直接使用回调,但是使用回调没有意义,因为我希望函数被多次调用。

(如果 class 关键字不清楚,我使用的是 ES6 和 Babel)。

编辑:似乎更好的方法是在调用 onClickCallback() 函数时向数组添加一个函数,然后创建一个调度函数,该函数循环遍历该数组调用所有函数,并将数据作为参数传递.

【问题讨论】:

    标签: javascript ecmascript-6 es6-modules


    【解决方案1】:

    如果一个回调应该被重用,它可以在构造时传递:

    class MyClass() {
        constructor(options) {
            // Set options
            // ...
    
            this.clickCallback = options.clickHandler;
        }
        ...
    }
    

    从构造函数参数或单个选项对象设置属性适用于可以设置实例属性的任何情况。

    但这意味着我只能定义 1 个外部函数。如果在计算 clickInfo 后需要调用多个函数怎么办?

    然后可以调用多个函数:

    new MyClass({
      clickHandler: clickInfo => {
        this.foo(clickInfo);
        this.bar(clickInfo);
      }
    });
    

    【讨论】:

    • 使用数组而不是对象来保存它们怎么样?更容易迭代数组。如果是这样,那么在实例化后还提供一个用于定义附加回调函数的函数是否有意义?做一个快速测试这似乎有效,但不确定它是否“正确”。
    • 刚刚意识到这是一个 lambda 函数而不是一个对象,但是关于定义额外回调的问题仍然存在。
    • 我想说这是 KISS 原则的主题。如果您不确定它为什么有益,请不要这样做。您需要将每个回调绑定到一个数组中,而单个箭头调用会使用适当的上下文调用它们。如果您觉得需要对回调进行更多控制,可以使用一些 pub-sub 库/事件发射器实现。例如。 RxJS 可以充当通用事件发射器。
    • 是的,我认为你的观点很好。认为我现在可能已经成为对此的一些分析瘫痪的受害者,所以还不如亲吻直到我需要更多。而且我正在使用带有 Vuex 的 Vue.js,所以我有一些 pub-sub 选项,但希望这些模块尽可能独立。感谢您的建议。有时只是尝试和谈论这些事情会有所帮助。
    • 很高兴它有帮助。
    猜你喜欢
    • 2016-03-08
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 2014-09-25
    相关资源
    最近更新 更多