Для такого кода:
editor.getSession().on('изменить', function() {
// Сделай что-нибудь
});
Я ожидаю, что это событие будет срабатывать только при взаимодействии с пользователем. Однако я обнаружил, что он срабатывает, когда я программно устанавливаю значение редактора, что не соответствует чему-то вроде, скажем, DOM. (Если вы добавите прослушиватель событий «change» для поля ввода, он не сработает, если мы установим значение с помощью JavaScript.)
Можно ли это исправить, и есть ли обходной путь или другое событие, которое срабатывает при обновлении значения редактора, но не программно?
@gissues :{"заказ":33.540372670807756,"статус":"отставание"}
По той же причине, по которой я отказался от CodeMirror в пользу ACE. Но код ACE намного легче читать. Я сделал патч, чтобы немного исправить это. Событие изменения по-прежнему запускается, но я добавил логическое свойство к объекту данных: userTyped. Будет true, если пользователь набрал или вставил текст в редактор. False, если он был введен программно. Это работает для моего конкретного случая использования в Chrome.
Это для файла ace-uncompressed.js из 0.2.0: http://dl.dropbox.com/u/310281/ace-patch.txt
я не думаю, что есть хороший способ разделить «программные» и пользовательские изменения (например, к какому типу принадлежит текст, введенный виджетом автозаполнения?)
и добавление userTyped
добавляет много бухгалтерии повсюду
если вам нужны только события ввода текста, вы можете добавить прослушиватель событий dom "input" в editor.container
или если вы хотите отфильтровать только свой собственный вызов setValue, добавьте флаг (аналогично $blockScrolling в editor.js)
это будет работать, поскольку событие «изменение» является синхронным
либо используйте метод, описанный в https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510, либо
editor.on("change", function(e) {
if (editor.curOp && editor.curOp.command.name) console.log("user change");
else console.log("other change")
})
Фрагмент, опубликованный nightwing, не работает должным образом, пока применяется копипаста. Другое решение, которое может решить проблему, похоже на это, например, с 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");
}
})
Что ж
$(document.activeElement).closest("div").attr("id") == "editordiv"
не работает, если у вас есть два редактора div, и они оба отредактированы focus()
, вы используете applyDeltas и пытаетесь их синхронизировать. Если я использую это неправильно, дайте мне знать. Но я почти уверен, что мне нужно другое решение.
Некоторое время назад была решена ошибка с отсутствием команды paste.
Проверка на наличие activeElement не сработает, и, как правило, не рекомендуется обращаться к dom из прослушивателя событий изменения, поскольку это снизит производительность редактора.
Используйте либо https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510
или https://github.com/ajaxorg/ace/issues/503#issuecomment-44525640
Могу ли я использовать # 1547 с applyDeltas? и с # 503, был ли groubis прав, когда говорил о копировании/вставке (потому что мне это тоже нужно?)
Я определенно мог пойти по поводу этой синхронизации неправильно, так что не исключайте этого, ха-ха :)
я только что попробовал
editor.on("change", function(e) {
if (editor.curOp && editor.curOp.command.name) console.log("user change");
else console.log("other change")
});
дословно, и когда я вставил, он сказал «другое изменение». У меня Сафари 9.0.1. Это поддерживаемая платформа?
Может быть, вы используете старую версию?
Подход, описанный в #1547, работает с applyDeltas.
Да, я так и думал, что вы имели в виду добавление объекта {silent:true}
в applyDeltas(delta, {silent:true})
. Сейчас я обновлен до последней версии, и я предполагаю, что моя проблема в том, что, хотя событие изменения является синхронным, я, кажется, сталкиваюсь с проблемой параллелизма, когда «тихая» блокировка блокирует удаленные дельты, пока локальный пользователь печатает .
Извините, в примере ошибка.
Он должен сказать
silent = true
editor.session.setValue("some text");
silent = false
и в прослушивателе изменений
if (silent) return
так что молчание - это переменная в вашем модуле, а не то, что вы передаете асу.
Обратите внимание, что применения applyDeltas недостаточно для синхронизации, так как вам нужно изменить дельты, чтобы учесть, что документ, к которому вы применяете, скорее всего, отличается от документа, для которого они были созданы.
Да, ошибка, с которой я столкнулся, не была связана с реальным API ace. Туз есть туз. Я столкнулся с проблемой параллелизма с несколькими (совместными) редакторами в одном документе, координируемом центральным сервером.
Эта проблема нетривиальна и требует так называемого оперативного преобразования; выходит далеко за рамки Ace. Для интересующихся: https://en.wikipedia.org/wiki/Operational_transformation.
Извините за неудобства, которые я причинил вашему замечательному проекту :/ ха-ха!
Самый полезный комментарий
либо используйте метод, описанный в https://github.com/ajaxorg/ace/issues/1547#issuecomment -22257510, либо