从已经导出的函数中导出函数

问题描述

我正在做一个项目,后端使用 Nodejs,使用 Parcel Bundler 编译的 vanilla JS 用于客户端 JS 和 PUG 模板引擎以生成视图。

请注意,我还使用了 FullCalendar v5 插件。我认为这无关紧要,因为我觉得没有它也会发生这种情况,但仍然是我目前遇到此问题的原因。

让我们进入正题:我有一个名为 initCalendar() 的“主”父函数。 它初始化日历,创建 FullCalendar 实例(以及所有日历方法),根据给定的配置设置它并在视图上呈现它。这个函数events.js 的顶级函数,我喜欢称之为“主”函数

initCalendar() 是使用 events.js 关键字从 export 导出的:export const initCalendar = () => { … }

在此之后,我编写了日历专有函数代码,这使我可以根据在日历上完成的操作执行我想要的任何操作。例如 eventClick(),顾名思义,它会在点击日历中的事件时执行。

重点是,我在这eventClick() 函数中创建了一些函数(它本身在 initCalendar() 中),其中一些我需要在 index.js 中使用。因此需要导出它们。此外,我无法将这些函数移出 initCalendar() 范围,因为我会丢失函数正常运行所需的重要变量,并且我想避免使用全局变量

我的自定义函数嵌套如下:initCalendar() -> eventClick() -> myFunction()(“main”导出的父函数 -> 中间日历函数 -> 我的函数(要导出))。

如果你想知道为什么我必须这样做,它是为了保持我迄今为止为项目的所有客户端 JS 使用的相同工作流程,尝试以“包裹方式”做到这一点.我有很多从许多不同文件导入到 index.js 中的导出函数,但是只有在我将 FullCalendar 包含在内时才会出现这个问题。

所以我现在找到的解决方案是直接从 eventClick() 导出我的函数,这次使用 exports 关键字:exports.myFunction = myFunction。这样做之后,我可以将它们导入 index.js 并继续使用我用于所有客户端 JS 的相同工作流程(请记住,使用 Parcel Bundler 编译)。

您如何看待这种“技术”?从已经导出的父函数中导出子函数不是不好的做法吗?

这对我来说似乎很棘手,我真的不喜欢那样……但我还没有找到更好的解决方案。 也许有人能给我一些关于是否可以这样做的见解,如果没有,如何以另一种方式解决问题?我想也许使用回调函数,但我无法做到以这种方式工作。

------- 编辑:一些代码-------

这是一些代码。我试着把它减到最少,因为 clickEvent() 函数代码字面上有一百行,而 FullCalendar 的代码更大。

events.js :如您所见,eventClick() 函数首先打开一个 Modal,其中包含所有事件信息(我没有写,因为不相关)和一个删除点击事件的按钮.

这个按钮应该设置他的 listenerindex.js 调用“导出的子函数removeEvent()click 事件中删除关联的事件数据库和日历。

那里还有其他相同风格的功能,但这个应该足以了解我在说什么。

// events.js

// … All the es6 imports : { Calendar } - { Modal } - axios; etc …


// As you can see,if I try to export the removeEvent() function from here,// it would work as exporting goes but I won't have the Modal instance of
// `eventInfoModal` used in `.then()`. Same thing with `const calendar`,// because they would not be in the scope of `initCalendar()`.
// Therefore I won't be able to call the functions I do on them in `.then()` 


export const initCalendar = () => {
    const calendarEl = document.getElementById('calendar');
    const calendar = new Calendar(calendarEl,{

        // … Ton of code to config FullCalendar,import the events,other calendar functions etc…
        
        eventClick: function(eventInfo) {
            const eventId = eventInfo.event.id;
            const infoModalContainer = document.getElementById('event-info-modal');
        
            // Modal created from an imported class     
            const eventInfoModal = new Modal(
                infoModalContainer,this.el
            );
                
            eventInfoModal.init();

            // … Lots of code to populate the modal with the event data,buttons etc …
        
            // So the point here is to call this function from index.js (code of index.js below)
            function removeEvent() {
                if (confirm('Êtes-vous sûr de vouloir supprimer ce RDV ?')) {
                    deleteEvent(eventId)
                      .then(() => {
                        eventInfoModal.close();
                        calendar.refetchEvents();
                      });
                }
            }

            // The "exported child function" I was talking about
            exports.removeEvent = removeEvent;

           // Then other functions defined and exported the same way,to be used just like removeEvent() in index.js
    
    });

    calendar.render();
    
    // Function called from removeEvent() in eventClick() above,just doing an axios DELETE request,no need to write it
    async function deleteEvent(eventId) {
       
    }
};

index.js在这里,我从其他文件中导入所有导出的函数(仅显示我们显然正在谈论的那个),并尝试按视图或“按类别”将我的听众分组和设置在一起,听众然后将调用从其他文件导入的相应函数,以执行所需的操作。

// index.js

// … All the es6 imports,including :
import { removeEvent } from './events';

const userEventsPage = document.getElementById('user-events');

if (userEventsPage) {
    const deleteEventBtn = document.getElementById('delete-event');

    userEventsPage.addEventListener('click',evt => {
        if (evt.target === deleteEventBtn) {
            removeEvent();
        }
    });
}

非常感谢

解决方法

发布我的评论作为答案,因为我相信这是解决此问题的正确方法。

您应该在创建模态时向 delete-event 按钮添加点击处理程序。

此外,从共享代码的外观来看,您的 Modal 应该具有类似于 onRemoveButtonClicked 的属性,该属性应该分配给您现在正在编写的 removeEvent 函数。我不明白你为什么需要导出它。