Вопрос

dependencies в атрибутах не работают в некоторых случаях

Добрый день, коллеги!

Столкнулся со следующей проблемой: в коде модуля, добавленного на панель инструментов, не обрабатывается событие при смене значений элементов на странице, например при добавлении в атрибутах конструкции:

"Candidate": {
	dependencies: [
		{
			columns: ["Candidate"],
			methodName: "onCandidateChanged"
		}
	]
}

, метод onCandidateChanged не вызывается. Для отслеживания изменений значения справочника помогла конструкция в массиве Diff:

                        "values": {

                            ...

                            "change": { "bindTo": "onCandidateChanged" }

                        }

Но для текстового поля такая конструкция не работает.

Подскажите, пожалуйста, как мне можно отследить изменение текстового поля в модуле на панели инструментов?

В качестве примера я пробую отловить изменение в текстовом поле стандартного элемента SocialMessagePublisherPage, и тоже ничего не получается. Но на обычных страницах (например, в карточках) всё прекрасно работает, и нужный метод вызывается при изменении значения поля.

Нравится

12 комментариев
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".
Показать все комментарии