Ace: Das Ereignis „change“ wird ausgelöst, wenn Ace programmgesteuert festgelegt wird

Erstellt am 14. Nov. 2011  ·  12Kommentare  ·  Quelle: ajaxorg/ace

Für Code wie diesen:

editor.getSession().on('change', function() {
// Etwas tun
});

Ich würde erwarten, dass dieses Ereignis nur ausgelöst wird, wenn eine Benutzerinteraktion vorliegt. Ich habe jedoch festgestellt, dass es ausgelöst wird, wenn ich den Wert des Editors programmgesteuert festlege, was nicht mit etwas wie beispielsweise dem DOM übereinstimmt. (Wenn Sie einen „change“-Ereignis-Listener für ein Eingabefeld hinzufügen, wird er nicht ausgelöst, wenn wir den Wert mit JavaScript festlegen.)

Kann dies behoben werden, und gibt es eine Problemumgehung oder ein anderes Ereignis, das ausgelöst wird, wenn der Wert des Editors aktualisiert wurde, aber nicht programmgesteuert?
@gissues :{"order":33.540372670807756,"status":"backlog"}

Hilfreichster Kommentar

Verwenden Sie entweder die in https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510 beschriebene Methode oder

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

Alle 12 Kommentare

Derselbe Grund, warum ich CodeMirror für ACE fallen gelassen habe. Aber der Code von ACE ist viel einfacher zu lesen. Ich habe einen Patch erstellt, um dies etwas zu beheben. Das Änderungsereignis wird immer noch ausgelöst, aber ich habe dem Datenobjekt eine boolesche Eigenschaft hinzugefügt: userTyped. Ist wahr, wenn der Benutzer Text in den Editor eingegeben oder eingefügt hat. False, wenn es programmgesteuert eingegeben wurde. Dies funktioniert für meinen speziellen Anwendungsfall in Chrome.

Dies ist für die ace-uncompressed.js-Datei von 0.2.0: http://dl.dropbox.com/u/310281/ace-patch.txt

Ich glaube nicht, dass es eine gute Möglichkeit gibt, "programmgesteuerte" und Benutzeränderungen zu trennen (z. B. zu welchem ​​​​Typ gehört Text, der vom Autocomplete-Widget eingegeben wurde?)
und das Hinzufügen userTyped fügt jede Menge Buchhaltung hinzu

Wenn Sie nur Texteingabeereignisse wünschen, können Sie den dom "input"-Ereignis-Listener zu editor.container hinzufügen
oder wenn Sie nur Sie herausfiltern möchten, fügen Sie Ihrem eigenen setValue-Aufruf ein Flag hinzu (ähnlich wie $blockScrolling in editor.js)
Es wird funktionieren, da das Ereignis "Änderung" synchron ist

Verwenden Sie entweder die in https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510 beschriebene Methode oder

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

Das von Nightwing gepostete Snippet funktioniert nicht so, wie es sollte, während Copy-Paste angewendet wird. Eine andere Lösung, die das Problem möglicherweise löst, ist so etwas, z. B. mit 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");
    }
})

Brunnen

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

funktioniert nicht, wenn Sie zwei Editor-Divs haben und beide focus() ed sind, Sie applyDeltas verwenden und versuchen, sie zu synchronisieren. Wenn ich das falsch benutze, lass es mich wissen. Aber ich bin mir ziemlich sicher, dass ich eine andere Lösung brauche.

Der Fehler, dass Einfügen keinen Befehl hat, wurde vor einiger Zeit behoben.
Die Suche nach activeElement funktioniert nicht, und es ist im Allgemeinen keine gute Idee, über den Änderungsereignis-Listener auf dom zuzugreifen, da dies die Leistung des Editors beeinträchtigt.

Verwenden Sie entweder https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510
oder https://github.com/ajaxorg/ace/issues/503#issuecomment -44525640

Kann ich aber #1547 mit applyDeltas verwenden? und mit #503, war groubis richtig, wenn es um kopieren/einfügen ging (weil ich das auch brauche?)

Ich könnte diese Synchronisierungssache definitiv auch falsch angehen - also schließe das noch nicht aus, haha ​​:)

Ich habe es versucht

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

wörtlich und als ich es eingefügt habe, hieß es "andere Änderung". Ich bin auf Safari 9.0.1. Ist das eine unterstützte Plattform?

Vielleicht verwendest du eine alte Version?
Der in #1547 beschriebene Ansatz funktioniert mit applyDeltas.

Ja, ich dachte, Sie meinten, das Objekt {silent:true} zu applyDeltas(delta, {silent:true}) hinzuzufügen. Ich bin jetzt auf die neueste Version aktualisiert, und ich denke, mein Problem ist, dass ich, obwohl das Änderungsereignis synchron ist, auf ein Parallelitätsproblem stoße, bei dem die "stille" Sperre Remote-Deltas sperrt, während der lokale Benutzer tippt .

Entschuldigung, im Beispiel ist ein Fehler aufgetreten.
Es sollte sagen

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

und im Wechsel Zuhörer

if (silent) return

so silent ist eine Variable in Ihrem Modul, nicht etwas, das Sie an ace übergeben.

Beachten Sie, dass die Verwendung von applyDeltas für die Synchronisierung nicht ausreicht, da Sie Deltas ändern müssen, um zu berücksichtigen, dass sich das Dokument, auf das Sie sich bewerben, höchstwahrscheinlich von dem Dokument unterscheidet, für das sie erstellt wurden.

Ja, der Fehler, den ich erlebte, hatte nichts mit der eigentlichen API von ace zu tun. Ass ist Ass – Ich hatte ein Parallelitätsproblem mit mehreren (kollaborativen) Editoren im selben Dokument, koordiniert von einem zentralen Server.

Dieses Problem ist nicht trivial und erfordert eine sogenannte operative Transformation; selbst weit über den Rahmen von Ace hinaus. Für Interessierte: https://en.wikipedia.org/wiki/Operational_transformation.

Entschuldigen Sie die Unannehmlichkeiten, die ich bei Ihrem großartigen Projekt verursacht habe :/ haha!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen