Добрый день, коллеги!
Столкнулся со следующей проблемой: в коде модуля, добавленного на панель инструментов, не обрабатывается событие при смене значений элементов на странице, например при добавлении в атрибутах конструкции:
"Candidate": {
dependencies: [
{
columns: ["Candidate"],
methodName: "onCandidateChanged"
}
]
}, метод onCandidateChanged не вызывается. Для отслеживания изменений значения справочника помогла конструкция в массиве Diff:
"values": {
...
"change": { "bindTo": "onCandidateChanged" }
}
Но для текстового поля такая конструкция не работает.
Подскажите, пожалуйста, как мне можно отследить изменение текстового поля в модуле на панели инструментов?
В качестве примера я пробую отловить изменение в текстовом поле стандартного элемента SocialMessagePublisherPage, и тоже ничего не получается. Но на обычных страницах (например, в карточках) всё прекрасно работает, и нужный метод вызывается при изменении значения поля.
Нравится
define("SocialMessagePublisherPage", [], function() {
return {
entitySchemaName: "SocialMessage",
mixins: {},
methods: {
init: function() {
this.callParent(arguments);
this.on("change:Message", this.onMessageChanged, this);
},
onMessageChanged: function(model, value, event) {
debugger;
}
},
diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
};
});
Варфоломеев Данила,
Спасибо! А есть ли вариант отловить события смены текста непосредственно в момент его изменения? В приведенном Вами примере событие срабатывает при потере фокуса у текстового поля.
Небеддаг Иван Владимирович пишет:
А есть ли вариант отловить события смены текста непосредственно в момент его изменения?
Есть, но надо конкретно так упороться:
1) Сворганить свой модуль, наследуется от Terrasoft.ESNHtmlEdit. В нём подменить функции onKeyUp. Сделать так, чтобы всегда отрабатывал fireEvent.
2) В странице SocialMessagePublisherPage переопределить SocialMessagePublisherEdit: className заменить на только что созданный модуль и забиндить свою функцию на event из функции fireEvent
3) Ну и как итог своя функция будет отрабатывать на каждый введенный/удаленный символ в поле.
Варфоломеев Данила,
забиндить свою функцию на event из функции fireEvent
Данила, добрый вечер, а можно поподробнее что именно нужно сделать. Все предыдущие шаги выполнил!
Не могли бы вы поподробнее рассказать (или выложить кусочек кода) о том как "забиндить свою функцию на event из функции fireEvent". Никак не получается сделать. Предыдущие шаги выполнить удалось!
Варфоломеев Данила,
"и забиндить свою функцию на event из функции fireEvent" - не могли бы Вы подробнее объяснить, каким образом это сделать?
Иван, видимо, он имел в виду как тут, только не на onClick, а на onKeyUp:
// Генерирует событие canExecute.
// Возвращает true, если можно продолжить выполнение метода onClick().
canExecute: function(config) {
var args = config.args;
var event = args[args.length - 1];
// Если метод onClick() был вызван из миксина CheckModuleDestroyMixin как callback-функция,
// то в него последним параметром передается событие, которое сигнализирует о прерывании выполнения.
if (event && event.isComeBack) {
return true;
}
// Добавление в аргументы события прерывания выполнения метода.
// Необходимо для остановки выполнения метода при вызове onСlick из callback-функции.
Array.prototype.push.call(config.args, {
isComeBack: true
});
// Применение текущего контекста.
Ext.apply(config, { scope: this });
// Генерация события canExecute.
var canExecute = this.fireEvent("canExecute", config);
return canExecute;
},Небеддаг Иван Владимирович,
mcNosferatum,
Извиняюсь за длительный ответ. В принципе да, Илья правильно объяснил. Если вы откроете ESNHtmlEditModule и посмотрите на функцию onKeyUp, то конкретно этот кусок кода
this.fireEvent("keyUp", keyboardEvent, this);отрабатывает только по условию (заключен в if). Конкретно для вашего случая нужно, чтобы сигнал посылался на каждое нажатие клавиши, поэтому fireEvent нужно вынести из под всех условий.
Upd. по быстрому набросал
Код модуля
define("UsrHtmlEditModule", ["ESNHtmlEditModule"],
function() {
//Ext.ns("Terrasoft.controls.UsrHtmlEditModule");
/**
* @class Terrasoft.controls.HtmlEdit
* Html editor control class.
*/
Ext.define("Terrasoft.controls.UsrHtmlEditModule", {
extend: "Terrasoft.ESNHtmlEdit",
alternateClassName: "Terrasoft.UsrHtmlEditModule",
onKeyUp: function(keyboardEvent) {
this.callParent(arguments);
this.fireEvent("keyPressed", keyboardEvent, this);
},
setInitConfig: function() {
this.callParent(arguments);
this.addEvents("keyPressed");
},
});
return Terrasoft.UsrHtmlEditModule;
});Код страницы
define("SocialMessagePublisherPage", ["UsrHtmlEditModule"], function() {
return {
entitySchemaName: "SocialMessage",
mixins: {},
methods: {
userPressedKey: function(event) {
debugger;
}
},
diff: /**SCHEMA_DIFF*/[
{
"operation": "merge",
"name": "SocialMessagePublisherEdit",
"values": {
"className": "Terrasoft.UsrHtmlEditModule",
"keyPressed": {bindTo: "userPressedKey"}
}
}
]/**SCHEMA_DIFF*/
};
});
Событие keyPressed действительно теперь отрабатывает при нажатии на каждую кнопку, но почему то this.Get("SocialMessagePublisherEdit") присылает не обновленное значение!
Сложно сказать наверняка. Вы можете провести отладку в браузере и посмотреть, возможно в свойстве хранится старое значение и меняется в какой-то другой момент. Либо же актуальное значение элемента находится в другом месте.
mcNosferatum пишет:
присылает не обновленное значение!
Видимо обновленное проставляется при unFocus событии элемента. Ну что ж. Можно тогда прокидывать введённое значение.
//в модуле:
this.fireEvent("keyPressed", keyboardEvent, this.getTypedValue(), this);
в странице:
userPressedKey: function(event, typedValue) {
var message = this.get("Message");
debugger;
}
Данила, спасибо! Все получилось, как хотел. Использовал :
var message = typedValue; - для получения текущего значения
var message = this.get("Message"); - теперь постоянно возвращает "undefined".