Para código como este:
editor.getSession().on('change', function() {
// Faça alguma coisa
});
Eu esperaria que esse evento fosse acionado apenas quando houver uma interação do usuário. No entanto, descobri que ele é acionado quando defino o valor do editor programaticamente, o que não é consistente com algo como, digamos, o DOM. (Se você adicionar um ouvinte de evento 'change' para um campo de entrada, ele não será acionado se definirmos o valor com JavaScript.)
Isso pode ser corrigido e existe uma solução alternativa ou um evento diferente que é acionado quando o valor do editor é atualizado, mas não programaticamente?
@gissues :{"order":33.540372670807756,"status":"backlog"}
Mesma razão pela qual eu larguei o CodeMirror para o ACE. Mas o código do ACE é muito mais fácil de ler. Eu fiz um patch para corrigir um pouco isso. O evento change ainda é acionado, mas adicionei uma propriedade booleana ao objeto de dados: userTyped. Será verdadeiro se o usuário digitar ou colar texto no editor. False se tiver sido inserido programaticamente. Isso funciona para o meu caso de uso específico no Chrome.
Isso é para o arquivo ace-uncompressed.js da versão 0.2.0: http://dl.dropbox.com/u/310281/ace-patch.txt
não acho que haja uma boa maneira de separar as alterações 'programáticas' e do usuário (por exemplo, a qual tipo pertence o texto inserido pelo widget de preenchimento automático?)
e adicionar userTyped
adiciona muita contabilidade em todo o lugar
se você quiser apenas eventos de entrada de texto, você pode adicionar o ouvinte de eventos dom "input" ao editor.container
ou se você quiser filtrar apenas sua própria chamada setValue, adicione um sinalizador (semelhante a $blockScrolling no editor.js)
funcionará desde que o evento 'change' seja síncrono
use o método descrito em https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510 ou
editor.on("change", function(e) {
if (editor.curOp && editor.curOp.command.name) console.log("user change");
else console.log("other change")
})
O snippet postado por nightwing não funciona como deveria enquanto copiar e colar é aplicado. Outra solução que pode resolver o problema é algo assim, por exemplo, com 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");
}
})
Nós vamos
$(document.activeElement).closest("div").attr("id") == "editordiv"
não funciona se você tem dois editor divs e ambos são focus()
ed, você está usando applyDeltas e está tentando sincronizá-los. Se eu estiver usando isso de forma errada, me avise. Mas tenho certeza que preciso de uma solução diferente.
O bug da pasta não ter comando foi resolvido há algum tempo.
A verificação de activeElement não funcionará e geralmente é uma má ideia acessar o dom a partir do ouvinte de eventos de mudança, pois isso prejudicará o desempenho do editor.
Use https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510
ou https://github.com/ajaxorg/ace/issues/503#issuecomment -44525640
Posso usar # 1547 com applyDeltas? e com #503, o groubis estava correto ao falar sobre copiar/colar (porque eu preciso disso também?)
Eu definitivamente poderia estar fazendo essa sincronização da maneira errada também - então não descarte isso ainda haha :)
acabei de tentar
editor.on("change", function(e) {
if (editor.curOp && editor.curOp.command.name) console.log("user change");
else console.log("other change")
});
literalmente e quando colei, disse "outra mudança". Estou no Safari 9.0.1. Essa é uma plataforma suportada?
Talvez você esteja usando a versão antiga?
A abordagem descrita em #1547 funciona com applyDeltas.
Sim, então eu pensei que você quis dizer adicionar o objeto {silent:true}
a applyDeltas(delta, {silent:true})
. Estou atualizado para a versão mais recente agora e acho que meu problema é que, embora o evento de alteração seja síncrono - parece que estou enfrentando um problema de simultaneidade em que o bloqueio "silencioso" bloqueará deltas remotos enquanto o usuário local está digitando .
Desculpe, houve um erro no exemplo.
Deve dizer
silent = true
editor.session.setValue("some text");
silent = false
e em mudança de ouvinte
if (silent) return
tão silencioso é uma variável em seu módulo, não algo que você passa para ace.
Observe que o uso de applyDeltas não é suficiente para a sincronização, pois você precisará alterar os deltas para levar em conta que o documento ao qual você está aplicando é provavelmente diferente do documento para o qual eles foram criados.
Sim, o bug que eu estava enfrentando não estava relacionado à API real do ace. Ace is ace - eu estava enfrentando um problema de simultaneidade com vários editores (colaborativos) no mesmo documento, coordenados por um servidor central.
Esse problema não é trivial, exigindo algo chamado transformação operacional; em si muito além do escopo de Ace. Para os interessados: https://en.wikipedia.org/wiki/Operational_transformation.
Desculpe por qualquer inconveniente que causei em seu grande projeto :/ haha!
Comentários muito úteis
use o método descrito em https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510 ou