Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

119
Views
¿Cómo se elimina la versión enlazada de un controlador de eventos?

Tengo un problema con mi evento de vinculación, me gustaría eliminar cada evento cuando se activa el evento de cambio. Está funcionando bien sin un bucle.

 this.objectInstance.on('selected', () => { document.querySelectorAll('select').forEach((el) => { this.test = this.fontFamilyHandler.bind(this, el.getAttribute('id')); el.addEventListener('change', this.test); }) }); this.objectInstance.on('deselected', () => { document.querySelectorAll('select').forEach((el) => { el.removeEventListener('change', this.test); }) }); fontFamilyHandler = (key, evt) => { this.objectInstance.set(key, evt.target.value); this.canvas.requestRenderAll(); }

¿Tienes alguna idea de por qué no funciona?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

En cada iteración, está sobrescribiendo this.test con el siguiente oyente. Entonces, al final, this.test contendrá el último oyente adjunto y, por lo tanto, solo puede eliminarlo.

Puedo ver dos soluciones aquí:

  1. Puede guardar todas las funciones de escucha y luego eliminarlas nuevamente, asignando el elemento al oyente:
 this.objectInstance.on('selected', () => { this.test = new WeakMap(); document.querySelectorAll('select').forEach((el) => { const handler = this.fontFamilyHandler.bind(this, el.getAttribute('id')); this.test.set(el, handler); el.addEventListener('change', handler); }) }); this.objectInstance.on('deselected', () => { document.querySelectorAll('select').forEach((el) => { if (!this.test.has(el)) continue; el.removeEventListener('change', this.test.get(el)); }) });

(Nota: usar solo una matriz no sería estable porque si cambia la cantidad de elementos <select> en el documento, los índices no estarían sincronizados).

(Nota: también funcionaría con Map en lugar de WeakMap , pero este último permite la recolección de elementos no utilizados antes de cualquier elemento <select> que se elimine del DOM).

  1. Use la misma función para todos los elementos, en lugar de vincularlos cada vez. Dado que accede al mismo elemento en el que está poniendo el oyente, y es un <select> , lo que significa que el evento de change solo provendrá del propio <select> , ya que no puede tener ningún elemento secundario que pueda enviar eventos de change , usando event.target.id también funciona:
 const eventHandler = event => this.fontFamilyHandler(event.target.id, event); this.objectInstance.on('selected', () => { document.querySelectorAll('select').forEach((el) => { el.addEventListener('change', eventHandler); }) }); this.objectInstance.on('deselected', () => { document.querySelectorAll('select').forEach((el) => { el.removeEventListener('change', eventHandler); }) });

(Nota: el.id es más fácil que el.getAttribute('id') y hace lo mismo; consulte Element#id ).

  1. O bien, puede usar fontFamilyHandler directamente y cambiarlo para leer el ID del elemento en sí.
 this.objectInstance.on('selected', () => { document.querySelectorAll('select').forEach((el) => { el.addEventListener('change', this.fontFamilyHandler); }) }); this.objectInstance.on('deselected', () => { document.querySelectorAll('select').forEach((el) => { el.removeEventListener('change', this.fontFamilyHandler); }) }); // I removed the `key` argument here this.fontFamilyHandler = evt => { this.objectInstance.set(evt.target.id, evt.target.value); this.canvas.requestRenderAll(); }
about 4 years ago · Juan Pablo Isaza Report

0

Del comentario anterior...

"Uno necesita ver el código circundante para comprender el problema real con el this lidiando el OP... Tengo especial curiosidad por fontFamilyHandler = (key, evt) => { /* ... */ } where esta función flota libremente frente a la línea 3 donde de repente se ve this.fontFamilyHandler.bind(this, el.getAttribute('id')); "

Hasta entonces, la siguiente respuesta proporcionada asume una especie de sintaxis/sistema de clase para una clase hipotética de MyType .

De causa la unión como con ...

 this.fontFamilyHandler.bind(this, el.getAttribute('id'));

... no es necesario en absoluto porque el OP ya accede al event.target dentro de este controlador que es igual al anterior el ...

 fontFamilyHandler = (key, evt) => { this.objectInstance.set(key, evt.target.value); this.canvas.requestRenderAll(); }

Por lo tanto, no es necesario vincular la id de cada elemento, ya que se puede acceder a esta propiedad a través de evt.target.id tanto como al valor ya a través evt.target.value .

Al final, el código se reducirá a algo mucho más legible como...

 //class MyType { // constructor() { // this.objectInstance = { on: () => {} }; this.objectInstance.on('selected', () => document .querySelectorAll('select') .forEach(el => el.addEventListener('change', this.fontFamilyHandler) ) ); this.objectInstance.on('deselected', () => document .querySelectorAll('select') .forEach(el => el.removeEventListener('change', this.fontFamilyHandler) ) ); this.fontFamilyHandler = ({ target }) => { this.objectInstance.set(target.id, target.value); this.canvas.requestRenderAll(); }; // } //}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!