DHTMLX Gantt in LWC

Aug 29 2020

Sto implementando il diagramma di Gantt DHTMLX in LWC. Sto cercando di chiamare un metodo LWC dalla funzione della libreria Gantt ma non funziona.

Ecco il codice:

<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);
}

Il openModalmetodo non viene chiamato perché thisnon è un riferimento valido nella libreria Gantt. Ho provato document.getElementByIdche non funziona neanche. Quali sono i modi in cui posso ottenere questo risultato?

Risposte

4 AnmolKumar Aug 29 2020 at 00:42

Quando provi a usare thisin a callback functionil contesto cambia e perdi il riferimento all'istanza della classe, leggi qui

La vecchia soluzione è memorizzare un riferimento a this(istanza di classe) in una variabile separata ( selfnell'esempio) e utilizzarlo nel callback

La soluzione moderna è usare la funzione Arrow che non ha un proprio thiscontesto e si riferisce al contesto della classe

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();
        });
    });
}