Ace: El evento 'cambiar' se dispara cuando se configura Ace programáticamente

Creado en 14 nov. 2011  ·  12Comentarios  ·  Fuente: ajaxorg/ace

Para código como este:

editor.getSession().on('cambiar', función() {
// Hacer algo
});

Esperaría que este evento solo se active cuando haya una interacción del usuario. Sin embargo, descubrí que se activa cuando establezco el valor del editor mediante programación, lo que no es coherente con algo como, por ejemplo, el DOM. (Si agrega un detector de eventos 'cambiar' para un campo de entrada, no se activará si establecemos el valor con JavaScript).

¿Se puede solucionar esto? ¿Existe una solución alternativa o un evento diferente que se active cuando el valor del editor se haya actualizado, pero no mediante programación?
@gissues :{"order":33.540372670807756,"status":"backlog"}

Comentario más útil

utilice el método descrito en https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510 o

editor.on("change", function(e) {
  if (editor.curOp && editor.curOp.command.name) console.log("user change");
  else console.log("other change")
})

Todos 12 comentarios

La misma razón por la que dejé CodeMirror para ACE. Pero el código de ACE es mucho más fácil de leer. Hice un parche para arreglar un poco esto. El evento de cambio aún se activa, pero agregué una propiedad booleana al objeto de datos: userTyped. Será verdadero si el usuario escribió o pegó texto en el editor. False si se ingresó mediante programación. Esto funciona para mi caso de uso específico en Chrome.

Esto es para el archivo ace-uncompressed.js de 0.2.0: http://dl.dropbox.com/u/310281/ace-patch.txt

No creo que haya una buena manera de separar los cambios 'programáticos' y del usuario (por ejemplo, ¿a qué tipo pertenece el texto ingresado por el widget de autocompletar?)
y agregar userTyped agrega mucha contabilidad por todas partes

si solo desea eventos de entrada de texto, puede agregar el detector de eventos dom "input" a editor.container
o si desea filtrar solo su propia llamada setValue, agregue una bandera (similar a $blockScrolling en editor.js)
funcionará ya que el evento 'cambio' es síncrono

utilice el método descrito en https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510 o

editor.on("change", function(e) {
  if (editor.curOp && editor.curOp.command.name) console.log("user change");
  else console.log("other change")
})

El fragmento publicado por nightwing no funciona como debería mientras se aplica copiar y pegar. Otra solución que puede resolver el problema es algo así, por ejemplo, con jquery:

editor.getSession().on('change', function() {
    if ($(document.activeElement).closest("div").attr("id") == "editordiv") {
        console.log("editor was changed by user typing or copy paste");
    } else {
        console.log("editor was changed programmatically");
    }
})

Bien

$(document.activeElement).closest("div").attr("id") == "editordiv"

no funciona si tiene dos divs de editor y ambos son focus() ed, está usando applyDeltas y está tratando de sincronizarlos. Si estoy usando esto incorrectamente, házmelo saber. Pero estoy bastante seguro de que necesito una solución diferente.

El error con el pegado que no tiene un comando se solucionó hace algún tiempo.
La comprobación de activeElement no funcionará y, por lo general, es una mala idea acceder a dom desde el detector de eventos de cambio, ya que degradará el rendimiento del editor.

Use https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510
o https://github.com/ajaxorg/ace/issues/503#issuecomment-44525640

Sin embargo, ¿puedo usar #1547 con applyDeltas? y con el n.º 503, ¿Groubis tenía razón al hablar de copiar/pegar (¿porque yo también necesito eso?)

Definitivamente podría estar haciendo esto de sincronización de la manera incorrecta, así que no lo descartes todavía jaja :)

acabo de intentar

editor.on("change", function(e) {
  if (editor.curOp && editor.curOp.command.name) console.log("user change");
  else console.log("other change")
});

textualmente y cuando pegué, decía "otro cambio". Estoy en Safari 9.0.1. ¿Es una plataforma compatible?

¿Quizás estás usando una versión anterior?
El enfoque descrito en #1547 funciona con applyDeltas.

Sí, pensé que te referías a agregar el objeto {silent:true} a applyDeltas(delta, {silent:true}) . Estoy actualizado a la última versión ahora, y supongo que mi problema es que, aunque el evento de cambio es síncrono, parece que me encuentro con un problema de concurrencia en el que el bloqueo "silencioso" bloqueará los deltas remotos mientras el usuario local está escribiendo .

Lo siento hubo un error en el ejemplo.
debería decir

silent = true
editor.session.setValue("some text");
silent = false

y en cambio oyente

if (silent) return

so silent es una variable en tu módulo, no algo que pasas a as.

Tenga en cuenta que el uso de applyDeltas no es suficiente para la sincronización, ya que deberá cambiar los deltas para tener en cuenta que el documento al que se aplica probablemente sea diferente del documento para el que se crearon.

Sí, el error que estaba experimentando no estaba relacionado con la API real de ace. As es as: estaba experimentando un problema de simultaneidad con varios editores (colaborativos) en el mismo documento, coordinados por un servidor central.

Ese problema no es trivial y requiere algo llamado transformación operativa; en sí mismo mucho más allá del alcance de Ace. Para los interesados: https://en.wikipedia.org/wiki/Operational_transformation.

Disculpa las molestias que he causado en tu gran proyecto :/ ¡jaja!

¿Fue útil esta página
0 / 5 - 0 calificaciones