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

Мне нужно при удалении элемента детали проверять последняя это строка или нет. Я в событии Deleting проверяю и если строка последняя, то бросаю эксепшен:   

throw new Exception("У СОба единственный застройщик. Его нельзя удалять. Перед удалением добавьте другого!");

При этом удаление не происходит, но пользователь видит сообщение: "Выделенные записи не получилось удалить" и по кнопке "посмотреть подробнее" ничего нет. Как я могу пробросить текст ошибки в отображаемое сообщение?

Нравится

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

Далеко не все исключения пробрасываются на клиент. Чтобы гарантированно отправить сообщение вы можете отправлять его по вебсокет-каналу, а на клиентской части обрабатывать ответ и выводить сообщение.

Пример отправки сообщения есть в исходном коде BaseVisa из пакета NUI, метод PublishClientVisaInfo. Пример обработки есть в клиентской схеме MLModelPage, функция subscribeServerChannelEvents.

Далеко не все исключения пробрасываются на клиент. Чтобы гарантированно отправить сообщение вы можете отправлять его по вебсокет-каналу, а на клиентской части обрабатывать ответ и выводить сообщение.

Пример отправки сообщения есть в исходном коде BaseVisa из пакета NUI, метод PublishClientVisaInfo. Пример обработки есть в клиентской схеме MLModelPage, функция subscribeServerChannelEvents.

Кто-то нашел работающий способ, чтобы кинуть "свое" сообщение в случае отмены удаления?

потому что мы не нашли.

 

  • если кидать ексепшн, то удаление не происходит, но выводится базовое окно "невозможно удалить" с пустым "подробнее".
  • если пробрасывать сообщение и возвращать фалсе, то все равно обьект удаляется (но сообщение ловится)
  • если пробрасывать сообщение и кидать ексепшн, то базовое окно "невозможно удалить" перекрывает наше сообщение (сообщение-то есть, только его можна обнаружить, если отлаживаться и идти пошагово, тогда оно "успевает" показаться)

 

также пробовался костыль, чтобы устанавливать в доп.поле признак, и сделать БП, который по сигналу "удаление обьекта" с таким признаком тупо "восстанавливает" запись. но. БП срабатывало, но нужную запись не вытягивало...

 

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

 

для справки, может, кому-то пригодится (да и себе на потомsmiley ). 

"проброска" сообщения с сервера на клиент:

 

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) {

надеюсь, информация будет полезной ) ну, и вдруг кто-то знает ответ на вопрос в начале (и, собственно, в заголовке темы)

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