DHTMLX Gantt en LWC

Aug 29 2020

Estoy implementando el diagrama de Gantt DHTMLX en LWC. Estoy tratando de llamar a un método LWC desde la función de la biblioteca de gantt pero no funciona.

Aquí está el código:

<template>
    <input type="hidden" id="hidden-task-data" onclick={openModal}/>
    <div class="thegantt" lwc:dom="manual" style='width:100%;'></div>
</template>

this.isModalOpen = false;

renderedCallback() {
    Promise.all([
            loadScript(this, DHTMLX7 + '/codebase/dhtmlxgantt.js'),
            loadStyle(this, DHTMLX7 + '/codebase/dhtmlxgantt.css')
    ]).then(() => {
        const root = this.template.querySelector('.thegantt');
        root.style.height = "300px";
        const gantt = window.Gantt.getGanttInstance();

        //This method is called when a user double clicks on a task bar of the chart
        gantt.attachEvent("onTaskDblClick", function(id, e) {
            /* As per LWC's documentation, this doesn't work
            let taskInput = document.getElementById("hidden-task-data");
            taskInput.value = e;
            taskInput.click();
            */
            this.openModal(); //This doesn't work
            return true;
        });
    });
}

openModal() {
    this.isModalOpen = true;
    console.log(this.isModalOpen);
}

No openModalse llama al método porque thisno es una referencia válida en la biblioteca de gantt. He probado lo document.getElementByIdque tampoco funciona. ¿Cuáles son las formas en que puedo lograr esto?

Respuestas

4 AnmolKumar Aug 29 2020 at 00:42

Cuando intenta usar thisen un callback functioncontexto cambia y pierde referencia a la instancia de clase, lea aquí

La solución anterior es almacenar una referencia a this(instancia de clase) en una variable separada ( selfen el ejemplo) y usarla en la devolución de llamada

La solución moderna es usar la función Arrow que no tiene su propio thiscontexto y se refiere al contexto de la clase

renderedCallback() {
    Promise.all([
            loadScript(this, DHTMLX7 + '/codebase/dhtmlxgantt.js'),
            loadStyle(this, DHTMLX7 + '/codebase/dhtmlxgantt.css')
    ]).then(() => {
        const gantt = window.Gantt.getGanttInstance();

        // Using Arrow function
        gantt.attachEvent("onTaskDblClick", (id, e) => {
            this.openModal();
        });

        // Storing reference of this in another variable
        const self = this;
        gantt.attachEvent("onTaskDblClick", function(id, e) {
            self.openModal();
        });
    });
}