Ace: L'événement 'change' se déclenche lors de la définition d'As par programmation

Créé le 14 nov. 2011  ·  12Commentaires  ·  Source: ajaxorg/ace

Pour un code comme celui-ci :

editor.getSession().on('change', function() {
// Faire quelque chose
});

Je m'attendrais à ce que cet événement ne se déclenche qu'en cas d'interaction de l'utilisateur. Cependant, j'ai constaté qu'il se déclenche lorsque je définis la valeur de l'éditeur par programme, ce qui n'est pas cohérent avec quelque chose comme, disons, le DOM. (Si vous ajoutez un écouteur d'événement 'change' pour un champ de saisie, il ne se déclenchera pas si nous définissons la valeur avec JavaScript.)

Cela peut-il être corrigé, et existe-t-il une solution de contournement ou un événement différent qui se déclenche lorsque la valeur de l'éditeur est mise à jour, mais pas par programmation ?
@gissues :{"order":33.540372670807756,"status":"arriéré"}

Commentaire le plus utile

soit utiliser la méthode décrite dans 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")
})

Tous les 12 commentaires

Même raison pour laquelle j'ai abandonné CodeMirror pour ACE. Mais le code d'ACE est beaucoup plus facile à lire. J'ai fait un patch pour corriger un peu ça. L'événement change est toujours déclenché, mais j'ai ajouté une propriété booléenne à l'objet de données : userTyped. Sera vrai si l'utilisateur a tapé ou collé du texte dans l'éditeur. Faux s'il a été saisi par programmation. Cela fonctionne pour mon cas d'utilisation spécifique dans Chrome.

C'est pour le fichier ace-uncompressed.js de 0.2.0 : http://dl.dropbox.com/u/310281/ace-patch.txt

Je ne pense pas qu'il existe un bon moyen de séparer les modifications "programmatiques" et utilisateur (par exemple, à quel type appartient le texte saisi par le widget de saisie semi-automatique ?)
et ajouter userTyped ajoute beaucoup de comptabilité partout

si vous ne voulez que des événements de saisie de texte, vous pouvez ajouter un écouteur d'événement "input" dom à editor.container
ou si vous souhaitez filtrer uniquement votre propre appel setValue, ajoutez un indicateur (similaire à $blockScrolling dans editor.js)
cela fonctionnera puisque l'événement 'change' est synchrone

soit utiliser la méthode décrite dans 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")
})

L'extrait posté par nightwing ne fonctionne pas comme il se doit lorsque le copier-coller est appliqué. Une autre solution qui peut résoudre le problème est quelque chose comme ça, par exemple avec 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"

ne fonctionne pas si vous avez deux divs d'éditeur et qu'ils sont tous les deux focus() ed, vous utilisez applyDeltas et vous essayez de les synchroniser. Si je l'utilise mal, faites le moi savoir. Mais je suis sûr que j'ai besoin d'une solution différente.

Le bug avec coller n'ayant pas de commande a été résolu il y a quelque temps.
La vérification de activeElement ne fonctionnera pas, et c'est généralement une mauvaise idée d'accéder à dom à partir de l'écouteur d'événement de changement, car cela dégradera les performances de l'éditeur.

Utilisez soit https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510
ou https://github.com/ajaxorg/ace/issues/503#issuecomment -44525640

Puis-je utiliser #1547 avec applyDeltas ? et avec #503, groubis avait-il raison de parler de copier/coller (parce que j'en ai besoin aussi ?)

Je pourrais certainement faire ce truc de synchronisation dans le mauvais sens aussi - alors n'excluez pas cela pour le moment haha ​​:)

je viens d'essayer

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

textuellement et quand j'ai collé, il a dit "autre changement". Je suis sur Safari 9.0.1. Est-ce une plate-forme prise en charge ?

Peut-être utilisez-vous l'ancienne version ?
L'approche décrite dans #1547 fonctionne avec applyDeltas.

Oui, donc je pensais que vous vouliez dire ajouter l'objet {silent:true} à applyDeltas(delta, {silent:true}) . Je suis mis à jour vers la dernière version maintenant, et je suppose que mon problème est que même si l'événement de changement est synchrone - je semble rencontrer un problème de concurrence où le verrou "silencieux" verrouille les deltas distants pendant que l'utilisateur local tape .

Désolé, il y avait une erreur dans l'exemple.
Il faudrait dire

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

et en changement d'auditeur

if (silent) return

donc silent est une variable dans votre module, pas quelque chose que vous passez à ace.

Notez que l'utilisation d'applyDeltas n'est pas suffisante pour la synchronisation, car vous devrez modifier les deltas pour tenir compte du fait que le document auquel vous postulez est très probablement différent du document pour lequel ils ont été créés.

Oui, le bogue que je rencontrais n'était pas lié à l'API réelle d'ace. Ace is ace - Je rencontrais un problème de simultanéité avec plusieurs éditeurs (collaboratifs) dans le même document, coordonnés par un serveur central.

Ce problème n'est pas trivial, nécessitant quelque chose appelé transformation opérationnelle; lui-même bien au-delà de la portée d'Ace. Pour les personnes intéressées : https://en.wikipedia.org/wiki/Operational_transformation.

Désolé pour tout inconvénient que j'ai causé sur votre grand projet :/ haha!

Cette page vous a été utile?
0 / 5 - 0 notes