Как в событии Deleting бросить исключение, чтобы текст отобразился пользователю
Здравствуйте!
Мне нужно при удалении элемента детали проверять последняя это строка или нет. Я в событии Deleting проверяю и если строка последняя, то бросаю эксепшен:
throw new Exception("У СОба единственный застройщик. Его нельзя удалять. Перед удалением добавьте другого!");
При этом удаление не происходит, но пользователь видит сообщение: "Выделенные записи не получилось удалить" и по кнопке "посмотреть подробнее" ничего нет. Как я могу пробросить текст ошибки в отображаемое сообщение?
Нравится
Далеко не все исключения пробрасываются на клиент. Чтобы гарантированно отправить сообщение вы можете отправлять его по вебсокет-каналу, а на клиентской части обрабатывать ответ и выводить сообщение.
Пример отправки сообщения есть в исходном коде BaseVisa из пакета NUI, метод PublishClientVisaInfo. Пример обработки есть в клиентской схеме MLModelPage, функция subscribeServerChannelEvents.
Далеко не все исключения пробрасываются на клиент. Чтобы гарантированно отправить сообщение вы можете отправлять его по вебсокет-каналу, а на клиентской части обрабатывать ответ и выводить сообщение.
Пример отправки сообщения есть в исходном коде BaseVisa из пакета NUI, метод PublishClientVisaInfo. Пример обработки есть в клиентской схеме MLModelPage, функция subscribeServerChannelEvents.
Кто-то нашел работающий способ, чтобы кинуть "свое" сообщение в случае отмены удаления?
потому что мы не нашли.
- если кидать ексепшн, то удаление не происходит, но выводится базовое окно "невозможно удалить" с пустым "подробнее".
- если пробрасывать сообщение и возвращать фалсе, то все равно обьект удаляется (но сообщение ловится)
- если пробрасывать сообщение и кидать ексепшн, то базовое окно "невозможно удалить" перекрывает наше сообщение (сообщение-то есть, только его можна обнаружить, если отлаживаться и идти пошагово, тогда оно "успевает" показаться)
также пробовался костыль, чтобы устанавливать в доп.поле признак, и сделать БП, который по сигналу "удаление обьекта" с таким признаком тупо "восстанавливает" запись. но. БП срабатывало, но нужную запись не вытягивало...
в общем, решили заменой базового метода "удалить" на свой (с вызовом базового, если все ок). у нас это деталь, которая в двух местах отображается (пока что), поэтому (пока что) должно хватить. но вопрос открытый, чисто на будущее, все-таки интересно, как решить эту проблему..
для справки, может, кому-то пригодится (да и себе на потом ).
"проброска" сообщения с сервера на клиент:
1) в скрипте БП или сервисе пишется строчка:
Terrasoft.Configuration.MsgChannelUtilities.PostMessage(UserConnection, "CannotDeleteFromTeamDetail", "CannotDeleteFromTeamDetail");
не забыть подключить скрипт Terrasoft.Configuration;
2) ищем скрипт ClientMessageBridge . если он есть в пользовательском пакете, то дописываем свое сообщение, если нету, наследуем от базового и пишем свое сообщение.
скрипт выглядит так (с одним нашим сообщением):
define("ClientMessageBridge", ["ConfigurationConstants"], function(ConfigurationConstants) { return { messages: { "CannotDeleteFromTeamDetail": { "mode": Terrasoft.MessageMode.BROADCAST, "direction": Terrasoft.MessageDirectionType.PUBLISH } }, methods: { init: function() { this.callParent(arguments); this.addMessageConfig({ sender: "CannotDeleteFromTeamDetail", messageName: "CannotDeleteFromTeamDetail" }); } } }; });
3) в клиенте, где нужно "поймать" сообщение подписываемся на него (у нас было в методе init детали):
блок месседж
messages: { "CannotDeleteFromTeamDetail": { mode: Terrasoft.MessageMode.BROADCAST, direction: Terrasoft.MessageDirectionType.SUBSCRIBE } }
метод инит
init: function() { this.callParent(arguments); this.sandbox.subscribe("CannotDeleteFromTeamDetail", function(args){ Terrasoft.showInformation("Невозможно удалить, т.к. для этого контакта есть записи Активностей в периоде!"); }, this); }
Замена базового метода меню детали "удалить" на свое:
1) в блок методов добавляем функцию:
getDeleteRecordMenuItem: function() { return this.getButtonMenuItem({ Caption: {"bindTo": "Resources.Strings.RemoveFromTeamMenuCaption"},//можно переименовать или оставить базовое название Удалить Click: {"bindTo": "removeFromTeamRecords"},//вызов своего метода Enabled: {bindTo: "isAnySelected"}, Visible: {bindTo: "IsEnabled"} }); },
2) свой метод removeFromTeamRecords -- по сути, часть базового (с проверками на выборку в реестре) с заменой вызовов базового метода удаления на свой checkCanRemoveFromTeamRecordsAndDelete, в котором сначала выполнить проверку условия (можно ли удалять), и если можно -- вызывать базовый метод deleteRecords()
removeFromTeamRecords: function() { const activeRow = this.getActiveRow(); if (activeRow && activeRow.isNew) { this.checkCanRemoveFromTeamRecordsAndDelete([activeRow.get("Id")], this); } else { const items = this.getSelectedItems(); if (!items || !items.length) { return; } this.checkCanRemoveFromTeamRecordsAndDelete(items, this); } }, checkCanRemoveFromTeamRecordsAndDelete: function(items, scope){ var msgOneContact = "Невозможно удалить, т.к. для этого Контакта есть записи Активностей в периоде!"; var msgManyContacts = "Невозможно удалить, т.к. среди Контактов есть Контакты с записями Активностей в периоде!"; var config = { serviceName: "MyService", methodName: "CanDeleteContactFromTeam", callback: function(response) { var result = response.CanDeleteContactFromTeamResult; this.canDelete = result; if (!!result){ scope.deleteRecords(); } else { Terrasoft.showInformation((items.length == 1) ? msgOneContact : msgManyContacts); } }, data: { TeamIds: items }, scope: scope, timeout: 10000 }; serviceHelper.callService(config); },
условие проверки выполнено через вызов веб-сервиса на сервере, код приводить уже не буду, есть примеры и почитать можно здесь и/или здесь.
также не забыть прописать в связи страницы serviceHelper (для нашего случая, т.к. используем вызов веб-сервиса)
define("MyDetail", ["ServiceHelper"], function(serviceHelper) {
надеюсь, информация будет полезной ) ну, и вдруг кто-то знает ответ на вопрос в начале (и, собственно, в заголовке темы)