Contexto: Fullcalendar v5 - Angular 13
Necesito incluir en cada evento un botón dinámico para realizar un método (myfunction) que se coloca en el archivo mecanografiado.
En las opciones de calendario, puedo trabajar en eventContent para agregar un html simple como un botón:
calendarOptions: CalendarOptions = { ... eventContent: { html: '<button mat-button>mybutton</button>' } }También puedo incluir un método javascript como una alerta incluyéndolo en el contenido del evento:
eventContent: { html: '<button mat-button onclick="alert(\'Hello\')">mybutton</button>' },Esto también funciona, PERO me gustaría activar un método que esté en mi modelo de mecanografiado y no en una función JS nativa.
Cuando intento con
eventContent: { html: '<button mat-button onclick="myfunction()">mybutton</button>' },esto no está funcionando...
y lo intenté obviamente
eventContent: { html: '<button mat-button (click)="myfunction()">mybutton</button>' },que ni siquiera está viendo el (clic).
Aparentemente, el compilador angular no funciona aquí ... entonces, ¿cómo puedo referirme a ese método?
Leí este botón personalizado para cada evento en ui-calendar fullcalendar PERO eso no es Angular y, por cierto, eventRender parece estar obsoleto y ya no está presente en v5 ahora.
Esto (a través de eventClick) tampoco funciona:
eventClick: function (info) { this.myfunction(info.event.id); }Finalmente probé:
views: { timeGridWeek: { //questo modifica TUTTI gli eventi in questa vista eventContent: function (event: any, element: any) { let eventWrapper = document.createElement('div'); eventWrapper.addEventListener("click",function(event){ console.log(event); }) eventWrapper.innerText = 'test dayGridWeek'; var arrayOfDomNodes = [eventWrapper]; return { domNodes: arrayOfDomNodes }; } }, },Pero nuevamente, esto funciona para un archivo console.log, no para un método/función personalizado de mi modelo.
Al final, ¿cómo puedo iniciar myfunction desde un botón agregado dinámicamente?
Así logré solucionarlo.
CalendarOptions es un objeto como cualquier otro objeto. ContentEvent es un objeto anidado colocado jerárquicamente dentro de CalendarOptions.
He escrito:
this.CalendarOptions.eventContent = function (arg: any) { //add time let timeText = document.createElement('div') timeText.className = "fc-event-time"; timeText.innerHTML = arg.timeText; //include additional info let additionalText = document.createElement('i') additionalText.className = "fc-event-title"; additionalText.innerHTML = arg.event.extendedProps.myproperty; //include img/icon that should work as a button let img = document.createElement('img'); img.src = '../../assets/sign_YES.svg'; img.className = "_iconFirma"; img.addEventListener("click", function (e: Event) { e.stopPropagation(); //prevents eventClick to be triggered this.anotherMethod(); //this is not working because here 'this' is the function }) let arrayOfDomNodes = [ timeText, additionalText, img ] return { domNodes: arrayOfDomNodes } }De esta manera, "esto" no podría usarse como una referencia al componente.
Así es como lo refactoricé, usando funciones de flecha para "traer" el componente para que sea "llamable" a través de "esto":
this.calendarOptions.eventContent = (arg: any) => { //add time let timeText = document.createElement('div') timeText.className = "fc-event-time"; timeText.innerHTML = arg.timeText; //include additional info let additionalText = document.createElement('i') additionalText.className = "fc-event-title"; additionalText.innerHTML = arg.event.extendedProps.myproperty; //include img/icon that should work as a button let img = document.createElement('img'); img.src = '../../assets/sign_YES.svg'; img.className = "_iconFirma"; img.addEventListener("click", (e: Event) => { e.stopPropagation(); //prevents eventClick to be triggered this.anotherMethod(); //this works now because 'this' is not the function anymore: it's the angular component }) let arrayOfDomNodes = [ timeText, additionalText, img ] return { domNodes: arrayOfDomNodes } }Este cambio de
function (argument) { //here 'this' is the function }a
(argument) => { //here 'this' is the component}(función de flecha plana) lo hace completamente diferente y deja que "este" sea el componente. Este enfoque diferente debe usarse tanto en la primera como en la segunda llamada de función.
De esta manera, podría agregar una imagen/icono dentro de cada evento y hacer que funcione como un botón