【发布时间】:2021-03-01 00:46:41
【问题描述】:
我正在做一个项目,使用 Nodejs 作为后端,使用 Parcel Bundler 编译的 vanilla JS 用于客户端 JS 和 PUG 模板引擎来生成视图。
请注意,我还使用 FullCalendar v5 插件。我认为这无关紧要,因为我觉得没有它可能会发生这种情况,但仍然是我目前遇到这个问题的原因。
让我们直奔主题:我有一个名为initCalendar() 的“主”父函数。
它初始化日历,创建 FullCalendar 实例(以及所有日历方法),根据给定的配置设置它并在视图上呈现它。这个函数是events.js 的顶层函数,我喜欢称之为“main”函数。
initCalendar() 使用 export 关键字从 events.js 导出:export const initCalendar = () => { … }。
在此之后,我编写了日历专有功能,允许我根据日历上的操作执行我想要的任何操作。比如eventClick(),只要点击日历中的一个事件就会执行,正如它的名字所暗示的那样。
重点是,我在这个eventClick() 函数中创建了一些函数(它本身在initCalendar() 中),其中一些我需要在index.js 中使用。因此需要将它们导出。另外,我不能将这些函数移到initCalendar() 范围之外,因为我会丢失我的函数正常运行所需的重要变量,并且我想避免使用全局变量。
我的自定义函数嵌套如下:initCalendar() -> eventClick() -> myFunction()(“主”导出父函数 -> 中间日历函数 -> 我的函数(要导出))。
如果您想知道为什么我必须这样做,它是为了保持我迄今为止对项目的所有客户端 JS 使用的相同工作流程,尝试“包裹方式” .我有很多从许多不同文件导入到index.js 中的导出函数,但是这个问题只有在我将 FullCalendar 包含在其中时才出现。
所以我现在找到的解决方案是直接从eventClick() 导出我的函数,这次使用exports 关键字:exports.myFunction = myFunction。这样做之后,我可以将它们导入 index.js 并继续使用我用于所有客户端 JS 的相同工作流程(请记住,使用 Parcel Bundler 编译)。
您如何看待这种“技术”?从已经导出的父函数中导出子函数不是不好的做法吗?
对我来说这似乎很老套,我不太喜欢这样……但我还没有找到更好的解决方案。 也许有人可以给我一些关于这样做是否可以的见解,如果不行,如何以另一种方式解决问题?我想也许可以使用回调函数,但我无法做到以这种方式工作。
------- 编辑:一些代码-------
这是一些代码。我试图将它缩减到最少,因为clickEvent() 函数的代码实际上有数百行,而 FullCalendar 的代码则更大。
events.js :如您所见,eventClick() 函数首先打开一个 Modal,其中包含所有事件信息(我没有写,因为不相关)和一个删除点击事件的按钮。
这个按钮应该让他的listener 设置为index.js 在click 事件上调用“导出的子函数”removeEvent(),以从数据库和日历中删除关联的事件。
里面还有其他相同风格的功能,但是这个应该足以明白我在说什么了。
// 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();
}
});
}
非常感谢
【问题讨论】:
-
我建议您添加更多的代码,而不仅仅是文字。这样更容易快速找到问题。除此之外,您能否添加足够的代码来说明原因:“我无法将这些函数移出 initCalendar() 范围,因为我会丢失我的函数正常运行所需的重要变量”我>
-
@maazadeeb 我想这样做,但实际上有大量代码......我会尽量减少它并更新帖子。
-
@maazadeeb 好了,我添加了一些相关代码
-
为什么不能在创建模态时给
delete-event按钮添加点击处理程序?从共享代码的外观来看,您的Modal应该有一个onRemoveButton属性,应该附加到您现在正在编写的removeEvent函数。我不明白你为什么需要导出它。
标签: javascript fullcalendar parceljs