Есть способ удалить контакт через OData использую api:

Изображение удалено.

Т.к. у контакта есть связь с другими сущностями, то контакт не удаляется. При удалении контакта, открывается форма, в которй предлагается удалить запись используя - Do not delete connected records, запись удаляется. Возможно ли использовать этот функционал в api, может добавить какой параметр в запрос надо?

Нравится

2 комментария

Изображение не дошло, использую Postman:

DELETE - {{creatio_base_url}}/0/odata/Contact/3a074f61-7e3f-e8dd-87e8-0f65722d0875

Ошибка:

{

    "error": {

        "code": "",

        "message": "An error has occurred."

    }

}

Добрый день, Владимир.

 

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

 

Обратите внимание, что данные настройки будут распространяться не только при удалении записи через OData, но и при удалении записи через интерфейс пользователя в Creatio CRM.

 

Детальнее об этих настройках можно найти в этой статье на Академии:

 

Показать все комментарии

Добрый день. Есть созданый нами сервис (по образцу базового ReportService), который возвращает по записи детали объекта pdf-файл. На десктопной версии креатио работа с ним настроена, возникли сложности с реализацией аналогичного в мобильном приложении.

По подробностям: на десктопе сервис на странице записи детали по нажатию кнопки получает значение поля и в ответ открывает файл на новой странице. Как именно что-то подобное сделать для записей детали на мобильном приложении? Есть ли какие-то нюансы с открытием pdf в мобильном приложении креатио?

Нравится

1 комментарий

Добрый день!

 

Позвольте привести пример скачивания и автоматического открытия файла с использованием базового FileService/GetFile (сервис и метод, которые триггерятся если в декстопной версии из детали с файлами выгрузить какой-либо файл) в мобильном приложении. Для этого:

1) Была создана кастомная кнопка в действиях на странице контакта в мобильном приложении

2) Был создан обработчик для нажатия на эту кнопку

Как это было достигнуто:

1) В конфигурации создать модуль UsrMyAction с кодом

Ext.define("Terrasoft.MyAction", {
	extend: "Terrasoft.ActionBase",
	config: {
		useMask: false,
		title: "MyActionTitle",
		iconCls: Terrasoft.ActionIcons.Copy
	},
 
	execute: function(record) {
		this.callParent(arguments);
		var config = {
			url: 'https://1168222internal-demo.creatio.com/0/rest/FileService/GetFile/e9eafee9-c4e4-4793-ad0a-003bd2c6a9b4/3bbbd5a8-8f8d-4570-8526-0488eb37da28',
			success: function(fullPath, relativePath) {
				Terrasoft.FileIntent.open({
					path: relativePath
				});
			}, 
			name: "Test_" + new Date().toDateString() + ".png"
		};
 
		Terrasoft.RequestManager.issueRequest({
					requestFn: Terrasoft.FileTransfer.download,
					requestFnConfig: config,
					responseToStatusCodeFn: Terrasoft.FileTransfer.getStatusCodeFromException,
					loginFailure: function(exception) {
						Ext.callback(config.failure, config.scope, [exception]);
					},
					suppressRequestEvents: config.suppressRequestEvents,
					scope: Terrasoft.FileTransfer
				});
		this.executionEnd(true);
	}
 
});

 

В нем создать локал.строку с кодом MyActionTitle и каким-то значением для этой локал.строки (например "Call custom service").

2) В конфигурации создать модуль UsrMobileContactModuleConfig с кодом

Terrasoft.sdk.Actions.add("Contact", {
    name: "myAction",
    actionClassName: "Terrasoft.MyAction"
});



3) В манифесте мобильного приложения добавить:

"CustomSchemas": [

"UsrMyAction"

],

...

"Models": {

...

"Contact": {

...

"PagesExtensions": [

"UsrMobileContactModuleConfig"

]

Пример манифеста из демо сайта для тестов, где тестировалась логика – файл MobileApplicationManifestDefaultWorkplace.txt ниже:

{
	"CustomSchemas": [
        "UsrMyAction"
    ],
	"SyncOptions": {
		"SysSettingsImportConfig": [
			"DefaultMessageLanguage"
		],
		"ModelDataImportConfig": [
			{
				"Name": "Contact",
				"SyncColumns": []
			},
			{
				"Name": "SysLanguage",
				"SyncColumns": []
			},
			{
				"Name": "ContactFile",
				"SyncColumns": [
					"Contact",
					"CreatedOn",
					"CreatedBy",
					"Name",
					"Data",
					"Type",
					"Size"
				]
			},
			{
				"Name": "FileGroup",
				"SyncColumns": []
			},
			{
				"Name": "ContactCommunication",
				"SyncColumns": [
					"CommunicationType",
					"Number",
					"Contact"
				]
			},
			{
				"Name": "CommunicationType",
				"SyncColumns": []
			},
			{
				"Name": "ContactAddress",
				"SyncColumns": [
					"AddressType",
					"Country",
					"Region",
					"City",
					"Address",
					"Zip",
					"Contact"
				]
			},
			{
				"Name": "AddressType",
				"SyncColumns": []
			},
			{
				"Name": "Country",
				"SyncColumns": []
			},
			{
				"Name": "Region",
				"SyncColumns": []
			},
			{
				"Name": "City",
				"SyncColumns": []
			},
			{
				"Name": "ContactAnniversary",
				"SyncColumns": [
					"Date",
					"AnniversaryType",
					"Contact"
				]
			},
			{
				"Name": "AnniversaryType",
				"SyncColumns": []
			},
			{
				"Name": "FileType",
				"SyncColumns": []
			},
			{
				"Name": "SocialMessage",
				"SyncColumns": [
					"EntityId"
				]
			}
		]
	},
 
	"Modules": {},
	"Models": {
		"ContactFile": {
			"RequiredModels": [
				"ContactFile",
				"FileGroup",
				"SocialMessage"
			],
			"ModelExtensions": [],
			"PagesExtensions": [
				"UsrMobileContactFileActionsSettingsDefaultWorkplace",
				"UsrMobileContactFileGridPageSettingsDefaultWorkplace",
				"UsrMobileContactFileRecordPageSettingsDefaultWorkplace"
			]
		},
		"SocialMessage": {
			"RequiredModels": [],
			"ModelExtensions": [],
			"PagesExtensions": []
		},
		"Contact": {
			"RequiredModels": [
				"Contact",
				"SysLanguage",
				"ContactFile",
				"FileGroup",
				"ContactCommunication",
				"CommunicationType",
				"ContactAddress",
				"AddressType",
				"Country",
				"Region",
				"City",
				"ContactAnniversary",
				"AnniversaryType",
				"FileType"
			],
			"ModelExtensions": [],
			"PagesExtensions": [
				"UsrMobileContactModuleConfig"
			]
		}
	},
	"ModuleGroups": {
		"main": {}
	},
	"UseUTC": true
}



4) Обязательно выполнить рисайкл пула приложения (не перезапуск сайта в IIS, а именно рисайкл пула).

Сама логика скачивания файла и его открытие реализована в модуле UsrMyAction:

var config = {

url: 'https://1168222internal-demo.creatio.com/0/rest/FileService/GetFile/e9e…

success: function(fullPath, relativePath) {

Terrasoft.FileIntent.open({

path: relativePath

});

},

name: "Test_" + new Date().toDateString() + ".png"

};

Terrasoft.RequestManager.issueRequest({

requestFn: Terrasoft.FileTransfer.download,

requestFnConfig: config,

responseToStatusCodeFn: Terrasoft.FileTransfer.getStatusCodeFromException,

loginFailure: function(exception) {

Ext.callback(config.failure, config.scope, [exception]);

},

suppressRequestEvents: config.suppressRequestEvents,

scope: Terrasoft.FileTransfer

});

Какие здесь ключевые моменты:

1) https://1168222internal-demo.creatio.com/0/rest/FileService/GetFile/e9e… получить файл (кстати, здесь можно немного заменить код на следующий:

var config = {

url: Terrasoft.CurrentUserInfo.serverUrl + '0/rest/FileService/GetFile/e9eafee9-c4e4-4793-ad0a-003bd2c6a9b4/3bbbd5a8-8f8d-4570-8526-0488

и результат будет тот же, просто не будет использоваться явная ссылка на корень приложения). Здесь нужно будет заменить его на URL к кастомному сервису.

2) "Test_" + new Date().toDateString() + ".png" - это название файла, который будет подгружен и автоматически открыт. Здесь важно еще контролировать расширение скачиваемого файла, но если в 100% случаев будет скачиваться PDF, то можно здесь просто захардкодировать расширение .pdf.

3) За подгрузку файла отвечает метод Terrasoft.RequestManager.issueRequest, в который мы передаем в config ссылку откуда нам нужно получить файл и что делать в случае успешного выполнения метода issueRequest (здесь можно добавить и failure обработчик).

4) На success п.3 запускается метод Terrasoft.FileIntent.open который и отвечает за автоматическое открытие файла.

Почему сделано так: при загрузке файла через Terrasoft.RequestManager.issueRequest сохранение происходит не в хранилище мобильного телефона, а в локальный кэш мобильного приложения и файл автоматически открывается, чтобы была возможность его сохранить уже в хранилище самого мобильного устройства. У нас нет встроенного метода, который позволил бы загрузить файл напрямую в мобильное устройство, только ручное хранение.

Ограничение: сервис по получению файла должен быть доступен через метод GET. Если сейчас у Вас он реализован через POST, то создайте рядом еще один метод специально для мобильного приложения и вызывайте в коде его (в URL вызова можно передавать значение аргументов для метода (например, ID записей файлов или т.д.)).

Что нужно заменить:

1) Кастомную кнопку с действием я добавлял на карточку контакта. Вы же можете ее добавить в карту детали с файлами (подход тот же, только вместо Contact – название объекта детали). Ну или можете динамически вычитывать записи из детали и выбирать подходящую.

2) Продумать как реализовать названия файлов (опять же, можно считывать оригинальный файл из детали, брать его название и вставлять в параметр name).

Результат (тестировал и на iOS физическом девайсе и в эмуляторе в Android studio):

1) Сама кнопка:

 

2) Нажатие на кнопку:

 

Далее файл можно сохранить:

 

 

потестируйте и продолжайте кастомизировать под Ваш сервис.

 

 

Показать все комментарии

Добрый день!

Абсолютно не могу понять, по какому принципу происходит сортировка записей при экспорте отчета. Ее можно как-то настроить?

Нравится

2 комментария

Здравствуйте, Александр, 

 

Детально данная информация описана на нашей Академии в соответствующей статье



С уважением, 

Анастасия

 

Александр, 

 

Приношу извинения за недопонимаем. Относительно сортировки в отчетах приложения Excel reports builder, на данный момент нет возможности настроить сортировку записей в данном решении.

Есть только базовая возможность задать перечень необходимых колонок для отчета. 



С уважением, 

Анастасия

Показать все комментарии

Коллеги, добрый день! Есть объект UsrOrder, в нем есть строковое поле JetOrderNumber. В конфигурации открываю этот объект, перехожу на вкладку События и включаю галочку "Перед сохранением записи" (UsrOrderSaving). Далее нажимаю на кнопку "Открыть процесс". Там создаю Событийный подпроцесс, начальным событием которого является Сообщение UsrOrderSaving, а после него создаю заданию-сценарий, в котором прописываю:

Entity.SetColumnValue("UsrOrderNumber", "новая запись");

throw new Exception("i123");

return true;

Далее сохраняю, публикую, компилирую. 

В итоге после сохранения поле UsrOrderNumber пустое, в консоли ничего нет, в Network ничего нет. Поможете мне понять почему ничего не происходит? Изображение удалено.

Нравится

1 комментарий

Добрый день.

 

На первый взгляд все должно работать.

Но если у вас пакет-сборка, то нет, так как в пакетах-сборках не работают событийные-процессы.



Та и вообще процессы использовать последнее время практика устарела. Лучше писать логику на объектах с помощью EntityEventListener. Такая логика будет работать и в пакетах-сборках.

Показать все комментарии

Вопрос по безопасному доступу к порталу https://academy.terrasoft.ua/docs/user/razvertyvanie_onsite/nastroika_dopolnitelnikh_parametrov_i_integraciy/bezopasnyj_dostup_k_portalu/nastroit_bezopasnyy_dostup_k_portalu Согласно статье, на портальном сервере надо отключить возможность входа для НЕпортальных пользователей. Таким образом, Supervisor так же не сможет зайти.

Уточните, каким образом предполагается производить компиляцию приложения, отвечающего за портал?

Нравится

1 комментарий
Лучший ответ

Добрый день,

 

Спасибо Вам за Ваш вопрос.

В этом случае мы рекомендуем рассматривать портал как отдельную ноду веб-фермы.

 

Таким образом, после всех изменений на главной ноде, просто переносите образ ноды на портальную.

Добрый день,

 

Спасибо Вам за Ваш вопрос.

В этом случае мы рекомендуем рассматривать портал как отдельную ноду веб-фермы.

 

Таким образом, после всех изменений на главной ноде, просто переносите образ ноды на портальную.

Показать все комментарии

Здравствуйте, Я нажимаю на печать MS Word отчет Word не запускается. На днях работал. У меня таков вопрос как посмотреть логирование чтобы узнать что происходить, когда Я нажимаю на печать. 

Нравится

1 комментарий

Здравствуйте!

 

Вы можете поискать ошибки в application logs, а также в Console и Network браузера в момент воспроизведения ошибки.

Если у Вас не получится исправить ошибки, напишите нам на support@creatio.com и предоставьте детали, чтобы мы могли Вам помочь.

 

С уважением,

Юлия Гриценко

Показать все комментарии

Добрый вечер!

столкунлся со след проблемой

я создаю новые записи в бизнес процессе след образом.

var schema = _connection.EntitySchemaManager.FindInstanceByUId(entityToMapId);
var newEntity = schema.CreateEntity(_connection);
newEntity.SetDefColumnValues();
 
newEntity.SetColumnValue(columnSchema, creatioValue);
 
newEntity.Save();

при этом я так же подписался на сигнал создания записей для той же схемы таким образом

Изображение удалено.

но этот сигнал не срабатывает при программном добавлении записей. что необходимо еще выполнить чтоб бизнесс процессы срабатывали должным образом?

Нравится

2 комментария
Лучший ответ

Добрый вечер.

 

Попробуйте вместо FindInstanceByUId использовать метод GetInstanceByName, как в примере ниже:

EntitySchema contactSchema = UserConnection.EntitySchemaManager.GetInstanceByName("Contact");
Entity contactEntity = contactSchema.CreateEntity(UserConnection);
contactEntity.SetDefColumnValues();
contactEntity.SetColumnValue("Name", "User01");
contactEntity.Save();

Напишите, если проблему удастся решить таким образом.

Добрый вечер.

 

Попробуйте вместо FindInstanceByUId использовать метод GetInstanceByName, как в примере ниже:

EntitySchema contactSchema = UserConnection.EntitySchemaManager.GetInstanceByName("Contact");
Entity contactEntity = contactSchema.CreateEntity(UserConnection);
contactEntity.SetDefColumnValues();
contactEntity.SetColumnValue("Name", "User01");
contactEntity.Save();

Напишите, если проблему удастся решить таким образом.

Спасибо за ответ! да, такой вариант сработал. в данный момент я выполняю такой код

 

var tempSchema = connection.EntitySchemaManager.FindInstanceByUId(entityId);
var schema = connection.EntitySchemaManager.GetInstanceByName(tempSchema.Name);

так как у меня хранится только гуид обьекта. есть лучше решение в данной ситуации?

Показать все комментарии

Добрый вечер!

Необходимо реализовать функционал массовой обработки контактов с помощью кода. получается мы создаем динамическую группу контактов и создаем фильтр. и потом мы хотим передать эту группу в сишарп код и там уже обработать.

К сожалению я пока не сильно понимаю, каким образом получить фильтр, который надо применить для выборки контактов, а так же как его потом применить в c# коде чтоб получить список контактов.

Так же наверно будет полезно сделать постраничную обработку данных в данном случае, потому что группа может быть большая.

Можете подсказать как это правильно делается/где найти пример?

 

Спасибо!

Нравится

2 комментария
Лучший ответ

Добрый день,

 

В системе есть класс CommonUtilities и метод GetFolderEsqFilters. Можно попробовать его использовать в Вашей задаче для того, чтобы вытащить фильтрацию из папки. Небольшой пример его использования есть в классе FolderConverter в методе CreateEntityDataEsq. Также есть пример в UpdateTargetAudienceProcessHelper (метод ProcessDynamicFolder (запускается при добавлении в аудиторию рассылки папки)). Потом эту фильтрацию вычитанную использовать для обработки записей.

Добрый день,

 

В системе есть класс CommonUtilities и метод GetFolderEsqFilters. Можно попробовать его использовать в Вашей задаче для того, чтобы вытащить фильтрацию из папки. Небольшой пример его использования есть в классе FolderConverter в методе CreateEntityDataEsq. Также есть пример в UpdateTargetAudienceProcessHelper (метод ProcessDynamicFolder (запускается при добавлении в аудиторию рассылки папки)). Потом эту фильтрацию вычитанную использовать для обработки записей.

Добрый вечер!

Спасибо за совет, это сработало хорошо. единственное пришлось копировать код в свой проект чтоб не было зависимостей на проект Terrasoft.Configuration. это правильно в данном случае?

Показать все комментарии

Добрый день.

Подскажите пожалйста, как можно изменить тип справочных записей (или запретить переход по ним) которые отображаются на секции раздела:

Изображение удалено.

Может как-то можно применить параметр "showValueAsLink": false на секции?

Нравится

4 комментария

Здравствуйте! На сколько я понял данные ссылки ведут на записи в других разделах. Запрет можно реализовать через роли. Запретить для данного пользователя чтение/редактирование. В общем нужно "поиграться" с правами доступа на записи

Тут больше речь о том, что пользователь не должен видеть "внутрянку" этой записи, куда ведет ссылка. Т.е. выбрать из справочника может, а проваливаться нет

Если ваши пользователи не умеют пользоваться настройкой колонок, то вы можете вывести поле Название из связанного объекта (например Клиент.ФИО), тогда будет отображаться его текстовое значение, но без ссылки. Но это будет работать до тех пор, пока пользователь не изменит настройки колонок у себя.

Такабаев Тимур,

Точно! спасибо)

Показать все комментарии

Добрый день!

Есть деталь, которая строит и отображает поля с esq фильтрами и вычисляемыми полями на странице.

При изменении значений и нажатии на кнопку сохранить, визуально видно что значения сохранены, но если переоткрыть страницу эти значения не сохраняються.

Если ли какой то способ сохранить данные поля?

Есть 4 группы полей :

    1. getPreviousValueItemConfig (Старое значение, itemType: this.Terrasoft.ViewItemType.MODEL_ITEM)

    2. getValueItemConfig (Значение, itemType: this.Terrasoft.ViewItemType.MODEL_ITEM) 

    3. getDeltaItemConfig (Дельта, itemType: this.Terrasoft.ViewItemType.MODEL_ITEM) 

    4. getLabelItemConfig 

    

    Поля строятся на основе следующего кода :

...
	methods: {
		/**
		   * Return row view config with delta and previous value columns
		   */
		  getDetailRowItemsWithVirtualColumnsViewConfig: function(item) {
			  const displayColumn = this.getValueType(item.$SpecificationType);
			  const rowViewConfig = [];
 
			  const column = this.findEntityColumn(displayColumn);
			  if (column) {
				  const columnName = column.name;
				  const dataValueType = column.dataValueType;
 
				  const containerItemConfig = {
					  itemType: this.Terrasoft.ViewItemType.GRID_LAYOUT,
					  name: columnName + "-grid-layout",
					  items: [
						  this.getValueItemConfig(columnName, dataValueType, displayColumn),
						  this.getPreviousValueItemConfig(columnName, dataValueType),
						  this.getDeltaItemConfig(columnName, dataValueType),
						  this.getLabelItemConfig(columnName)
					  ],
					  // index: 0
				  };
				  rowViewConfig.push(containerItemConfig);
			  }
 
			  return rowViewConfig;
		  },
 
		  /**
		   * Returns value type.
		   * @public
		   * @return {String} Value type.
		   */
		  getValueType: function(dataType) {
			  switch (dataType.value) {
				  case SpecificationBuilderConstants.SpecificationType.Lookup:
					  return "SpecificationListItem";
				  case SpecificationBuilderConstants.SpecificationType.Text:
					  return "TextValue";
				  case SpecificationBuilderConstants.SpecificationType.Float:
					  return "FloatValue";
				  case SpecificationBuilderConstants.SpecificationType.Integer:
					  return "IntegerValue";
				  case SpecificationBuilderConstants.SpecificationType.Boolean:
					  return "BooleanValue";
				  default:
					  return "";
			  }
		  },
 
		  /**
		   * Returns label config for row
		   * @param {String} columnName
		   * @returns {Object}
		   */
		  getLabelItemConfig: function(columnName) {
			  const labelItemConfig = {
				  itemType: this.Terrasoft.ViewItemType.LABEL,
				  id: columnName + "-label-" + this.Terrasoft.generateGUID(),
				  name: columnName + "-label-" + this.Terrasoft.generateGUID(),
				  caption: {
					  bindTo: "Caption"
				  },
				  layout: {
					  row: 0,
					  column: 0,
					  colSpan: 6,
					  rowSpan: 1
				  }
			  };
 
			  if (columnName !== "BooleanValue") {
				  labelItemConfig.isRequired = {
					  "bindTo": "getControlRequired"
				  };
			  }
			  return labelItemConfig;
		  },
 
		  /**
		   * Returns previous value control config for row
		   * @param columnName
		   * @param dataValueType
		   * @returns {Object}
		   */
		  getPreviousValueItemConfig: function(columnName, dataValueType) {
			  return {
				  itemType: this.Terrasoft.ViewItemType.MODEL_ITEM,
				  dataValueType: dataValueType,
				  id: columnName + "-previousValue-" + this.Terrasoft.generateGUID(),
				  name: columnName + "-previousValue-" + this.Terrasoft.generateGUID(),
				  caption: this.get("Resources.Strings.PreviousValueCaption"),
				  visible: {
					  bindTo: "ControlVisible",
					  bindConfig: {
						  converter: function() {
							  return this.getControlVisible(columnName);
						  }
					  }
				  },
				  layout: {
					  row: 0,
					  column: 6,
					  colSpan: 6,
					  rowSpan: 1
				  },
				  enabled: this.$CanChangeOppProductConditionSpecificationFieldsDetailAttr,
				  bindTo: "PreviousValue"
			  };
		  },
 
		  /**
		   * Returns value control config for row
		   * @param {String} columnName
		   * @param {Terrasoft.DataValueType} dataValueType
		   * @param {String} displayColumn
		   * @returns {Object}
		   */
		  getValueItemConfig: function(columnName, dataValueType, displayColumn) {
			  const valueItemConfig = {
				  itemType: this.Terrasoft.ViewItemType.MODEL_ITEM,
				  dataValueType: dataValueType,
				  id: columnName + "-" + this.Terrasoft.generateGUID(),
				  name: columnName + "-" + this.Terrasoft.generateGUID(),
				  caption: this.get("Resources.Strings.ValueCaption"),
				  layout: {
					  row: 0,
					  column: 12,
					  colSpan: 6,
					  rowSpan: 1
				  },
				  bindTo: displayColumn,
				  enabled: {
					  bindTo: "isEditable"
				  }
			  };
 
			  if (dataValueType === Terrasoft.DataValueType.LOOKUP) {
				  valueItemConfig.contentType = Terrasoft.ContentType.ENUM;
			  }
			  return valueItemConfig;
		  },
 
		  /**
		   * Returns delta value control config for row
		   * @param columnName
		   * @param dataValueType
		   * @returns {Object}
		   */
		  getDeltaItemConfig: function(columnName, dataValueType) {
			  return {
				  itemType: this.Terrasoft.ViewItemType.MODEL_ITEM,
				  dataValueType: dataValueType,
				  id: columnName + "-deltaValue-" + this.Terrasoft.generateGUID(),
				  name: columnName + "-deltaValue-" + this.Terrasoft.generateGUID(),
				  caption: this.get("Resources.Strings.DeltaValueCaption"),
				  visible: { "bindTo": "getIsDeltaVisible" },//isNumberValue,
				  layout: {
					  row: 0,
					  column: 18,
					  colSpan: 6,
					  rowSpan: 1
				  },
				  enabled: this.$CanChangeOppProductConditionSpecificationFieldsDetailAttr,
				  bindTo: "DeltaValue"
			  };
		  }
	}
...

 

Нравится

2 комментария

Визуально деталь выглядит так :

Добрый день!

В данном случае боюсь не выйдет определить причину такого поведения без проведения дебага логики этой детали. Со своей стороны скажу, что при изменении поля должен вызываться базовый метод onItemChanged, который отправляет сообщение "itemChanged". Следует проверить путь этого сообщения на наличии препятствий его обработки. Далее стоит проверить логику вызова базового метода onSaved, что он делает и что происходит далее. Точно не скажу в каких конкретно схемах искать данные методы, лучше вбить их в поиск dev tools и поставить брейкпоинты в них и смотреть, что конкретно вызывается и в какой последовательности.

Показать все комментарии