Если "повесить" зависимость некоторого атрибута на колонку, в методе-обработчике зависимости изменять значение колонки-зависимости - вполне предсказуемо получить рекурсивный вызов. Но обычно цепочка рекурсивных вызовов пресекается установкой флага, или внедрением проверок, которые гарантированно не пройдут при повторном вызове, что в свою очередь обеспечит выполнение рекурсивного вызова без изменения целевого значения.
В данном случае, не зависимо от механики предусмотренной в методе-обработчике, его вызов уходит в рекурсию в том случае если во время его исполнения было изменено значение зависимой колонки.
н/п
так вот несмотря на то, что при повторном вызове обработчика, выполнение уходит в ветку
... if(window.foo){
window.foo=false;
...
после чего, рекурсивные вызовы, по идее, должны закончиться т.к. значение "TargetColumn" более не меняется, по факту вызовы SameHandlerControl уходят в бесконечную рекурсию
Как этого избежать ?
Почему так происходит ?
PS: классический кейс "самоконтроля поля ввода" - поле реагирует на изменение своего значения вызовом обработчика, который производит проверки и вычисления с введенным значением, по необходимости корректируя/восстанавливая свое собственное значение, предотвращая рекурсивный вызов обработчика.
Здравствуйте
Интересный случай. Глубоко не копал, но причина вроде бы в последовательности вызова
меняя this.set("TargetColumn", new Date());, вы "дергаете" SameHandlerControl, т.к. атрибут связан с колонкой. И поскольку перед "самовызовом" метода вы меняете флаг выхода, то получается замкнутый цикл
попробуйте вызвать window.foo = true; ПОСЛЕ this.set("TargetColumn", new Date());
мой тестовый код, на котором нет вечного цикла
define("UsrSection1Page", [], function(){return{
entitySchemaName:"UsrSection",
attributes:{"SameHandler":{
dependencies:[{
columns:["UsrName"],
methodName:"SameHandlerControl"}]}},
methods:{"SameHandlerControl": function(){
var n =this.get("UsrName");if(window.foo){
window.foo=false;}else{//window.foo = true;this.set("UsrName", n + window.foo);
window.foo=true;}}},
...
Я решил, проблему "отложенным вызовом на 100 мс." смены атрибута который приводит к вызову обработчика в рекурсии
...
setTimeout(function(){this.set("TargetColumn", new Date())}.bind(this), 100);
...
т.е. как только выполнение обработчика завершается корректно - повторный вызов из отложенной функции уже корректно ловит "флаг" и его обрабатывает.
PS: создается такое впечатление что срабатывание обработчиков - псевдосинхронное, т.е. this.set банально "стакает" текущий контекст, и функция вызывается повторно, не завершившись в предыдущий раз.
У нас разработан конфигурационный сервис (C#), который считывает из БД Oracle набор записей, создает из них объекты и записывает эти объекты в некий набор таблиц MSSQL (БД CRM Terrasoft).
Запись объектов в таблицы MSSQL производится конструкцией типа new Insert(_userConnection).Into("название таблицы"). К сожалению подобная конструкция подразумевает запись только одного объекта за раз.
Подскажите, пожалуйста, каким образом мы можем переделать данный механизм под пакетную загрузку, чтобы запись в MSSQL таблицу осуществлялась пакетно, то есть например по 100 объектов за раз?
Если бы данные выбирались из той же базы, можно было бы new InsertSelect, внутри которого бы был запрос на выборку. Но Oracle и MSSQL одновременно...:mrgreen:
В принципе, можно запустить произвольный SQL-запрос при помощи new CustomQuery, а в него и передать текстом запрос на вставку 100 записей.
В бизнес процессе вызываю преднастроенную страницу со своей логикой. Но после ее вызова в БП висит "Выполняется" на преднастроенной страницы. Как сделать чтобы преднастроенная страница считалась "Выполненной" и продолжить выполнение бизнес процесса?
Для того, чтобы элемент [Преднастроенная страница] считался выполненным и процесс перешел к выполнению следующего элемента необходимо – в схеме страницы вызывать метод completeExecution().
Пример можно найти схеме страницы распределения лида - LeadManagementDistributionPageV2
7.10 (Sales)
В типовой карточке Активности (LeadPageV2), поле DetailedResult потребовалось установить его обязательность для заполнения в зависимости от определенных условий и действий пользователя.
в замещающей схеме был добавлен аттрибут
ну и собственно сам метод "DetailedResultRequireController",
н/п упростим его до тривиальности -
methods:{
... "DetailedResultRequireController":function(){ var targetStage =this.get("Status"); var targetResult =this.get("Result"); var requireState =false; if(targetStage.displayValue==="Завершена"&& targetResult.displayValue==="Отменена"){
requireState =true; } this.set("DetailedResultRequire", requireState); }
...
который производит некие проверки и устанавливать/сбрасывать значение целевого атрибута "DetailedResultRequire", тем самым контролируя обязательность поля "Результат подробно" PS: Аналогичные кейсы реализовывались множество раз в других типовых карточках и карточках собственной разработки.
В конечном итоге, поведение весьма удивительное.
Зависимость от изменения значения поля "Результат" => срабатывает.
Метод-обработчик выполняется => устанавливает значение атрибута
=> у искомого поля появляется "*" (звездочка) [т.е. view реагирует на смену значения атрибута] но это не мешает произвести сохранение карточки, штатные механизмы валидации или игнорируют сей факт или не выполняются вовсе
вот как-то так это выглядит (GIF-ка):
Ума не приложу где можно было бы искать проблему.
Возможно у пользователей сообщества возникали аналогичные ситуации, или есть идеи на счет причин такого поведения ?
Бизнес-правила, это бизнес-правила, это здесь не при чем. :smile:
Почему может не работать "привязка" обязательности к атрибуту ? - вот вопрос.
Такая логика с точки зрения архитектуры - более чем допустима, до появления бизнес-правил в "перерожденном виде" это использовалось везде и всюду.
Хочется понять природу проблемы.
"Севостьянов Илья Сергеевич" написал:Почему "звездочка" есть
А валидации - нет ?
Исходя из того, что обсуждается в этой теме http://www.community.terrasoft.ru/forum/topic/12633, такая проблема была обнаружена в более ранних версиях, но, судя по Вашему примеру, так до сих пор и не решена.
В 7.8 и 7.9 активно пользовались биндингами к isRequired, работало нормально, судя по всему в 7.10 наблюдается эта проблема, скорее всего как раз из-за "новых бизнес-правил".
Очень ждем версии с решением, т.к. много кода связано с этими биндингами, да и бизнес-правилами сложную логику не реализовать никак.
Как временное решение - добавлять бизнес правила, которые в зависимости от значения именно атрибута (на который делался биндинг) будет устанавливать обязательность.
Т.е. все ваши биндинги к isRequired необходимо повторить в бизнес-правилах.
Возник вопрос, кто знает как предусмотреть пакетный перенос значений справочника через данные если требуется перенести новые значения базового справочника так, чтобы старые были, допустим, удалены и заменены на новые?
Или необходимо скриптом производить insert, а потом update (в тех сущностях где они используются) и delete старых значений?
1. Вы можете в справочник добавить признак 'IsNotUsed' и реализовать следующую логику в тех сущностях, где значения этого справочника используются: если у записи установлен признак 'IsNotUsed', то в полях новых записей этих сущностей значения не отображать. Конечно, нужно будет записать запрос, который проапдейтит нужные записи справочника и установит признак 'IsNotUsed' в true. Соответственно включить всю эту логику в пакет переноса.
2. Пойти описанным Вами путем - в пакет переноса включить скрипты с инсертом новых записей, апдейтом в сущностях, которые ссылаются на данный справочник, делитом старых значений.
Добрый день, столкнулся с такой проблемой после переноса изменение из svn разделы не добавились в список разделов, после изучения бд выяснил что о разделах не было записи в таблицах SysModuleEntity, SysModuleEdit, SysModule после добавления в эти таблицы разделы начали отображаться в списке разделом но при добавлении и их в рабочее место рабочее место не загружается и в консоли появлятся ошибка
user: dgolovachev/e7f5fff2-2fea-4aa6-b704-b306cf31b654 file: undefined
line: undefined
column: undefined
message: Cannot read property 'imageId' of undefined
date: Tue May 30 2017 14:42:26 GMT+0600 (Central Asia Standard Time)
moduleId: ext-window
moduleName: undefined
подскажите в каком направлении необходимо копать заранее благодарен.
В целом, если раздел не был корректно зарегистрирован мастером в БД, лучшее решение - создать заново, ибо мастер гарантированно внесет все необходимые привязки.
Если всеже хотите пойти сложным путем, вот необходимый минимум таблиц, в которых раздел нужно зарегистрировать(тестировали на 7.9.2):
I Этап. Создать запись в таблице SysModuleEntity (таблица, где хранится информация объектах разделов):
SysModuleEntity
insert into SysModuleEntity (SysEntitySchemaUId) values ('AF6DD4AD-1398-4FCE-8837-78DC65AE0F9E')
где [SysEntitySchemaUId] - колонка Uid объекта раздела (например, "UsrRK") в таблице SysSchema;
II Этап. Создать запись в таблице SysModuleEdit (страница редактирования "Page"):
где [SysModuleEntityId] - колонка Id записи таблицы SysModuleEntity из первого этапа (проверка Select Id from SysModuleEntity Where SysEntitySchemaUId='AF6DD4AD-1398-4FCE-8837-78DC65AE0F9E')
[CardSchemaUId] - колонка Uid страницы редактирования объекта (например, "UsrRK1Page") в таблице SysSchema (проверка Select Uid,Name from SysSchema where name like '%UsrRK%'). Нам необходима схема, которая называется "Название объекта + 1Page"
[ActionKindCaption] - Название кнопки в реестре раздела;
[ActionKindName] - Название схемы страницы редактирования;
[PageCaption] - Заголовок схемы страницы редактирования в таблице SysSchema (проверка Select Uid,Name,Caption from SysSchema where name like '%UsrRK1Page%')
III Этап. Создать запись в таблице SysModule (страница раздела "Section"):
где [Caption] - Название раздела (можно брать caption объекта раздела -
[SysModuleEntityId] - колонка Id записи таблицы SysModuleEntity из первого этапа (проверка Select Id from SysModuleEntity Where SysEntitySchemaUId='AF6DD4AD-1398-4FCE-8837-78DC65AE0F9E')
[Code] - Название объекта раздела;
[SectionModuleSchemaUId] - UId модуля SectionModuleV2 с помощью которой открывается схему раздела;
[SectionSchemaUId] - колонка Uid страницы раздела объекта (например, "UsrRK1Section") в таблице SysSchema (проверка Select Uid,Name,Caption from SysSchema where name like '%UsrRK%'). Нам необходима схема, которая называется "Название объекта + 1Section"
Регистрировал раздел по вашему алгоритму, т.к. мастер у меня упорно не хочет работать. Вроде бы все заработало, но столкнулся с такой проблемой: если создать делать, которая будет ссылаться на нашу новую сущность, то при формировании ссылки на карточку этого раздела ссылка будет некорректной. "Вскрытие" показало, что причина в отсутствии записи в таблице SysModule в колонке CardModuleUId. Без этой записи ссылка формируется без CardModuleV2 и карточка не открывается.
В пакете, после попытки сохранить изменения для выполняющегося процесса, создалась копия для новой версии процесса. Новую копию сделал актуальной в свойствах процесса, но как теперь удалить изначальную версию, чтобы "не тащить" ее на промышленную среду из среды разработки?
Стандартный функционал удаления схемы процесса (его некоторой версии) приводит к удалению всех схем данного бизнес-процесса из пакета.
Создание новой версии процесса подразумевает создание новой схемы, которая ссылается на оригинальную схему БП.
Удалить оригинальную схему БП без всех остальных версий не получится.
Только на прошлой неделе удаляла копию БП, при этом удалялись все запущенные экземпляры данного процесса-копии, если таковые имелись, но в моем случае таких вроде не было, а родительский процесс (из которого делала копию) остался.
Он был неактивен и активировала я его через действие [Set as actual] прямо в дизайнере БП.
Используемая версия 7.10.0.
Если у Вас версия ниже данной, то, возможно, что вариант, предложенный Владимиром подойдет больше.
Задача решилась небольшим шаманством :) с файлами descriptor.json и properties.json.
Из первого файла удалил секцию Parent (ссылка на первую версию процесса), а во втором файле указал "Version": "0" и "IsActiveVersion": "True". Все изменения производил в Visual Studio.
Затем загрузил изменения в файловой системе в Конфигурацию, и удалил из Конфигурации первую версию процесса уже как независимый процесс.
Решение выше оказалось не рабочим, при попытке сохранить отредактированную диаграмму процесса стало вылетать исключение: http://prntscr.com/fe4sw8
Пришлось через меню "Действия" в диаграмме процесса создавать копию процесса, а старый удалять.
Появилась потребность формировать фильтры для динамических групп автоматически, собственно, нашел как они формируются из JS-ного кода и хранятся в таблице [раздел]Folder в виде шестнадцатеричного кода. Вопрос, как формировать и сериализовывать их для записи в таблицу?
"Шамшин Олег" написал:Вопрос, как формировать и сериализовывать их для записи в таблицу?
Для нашего "узкого" вопроса мы формировали их, копировали код в справочник, а потом использовали. То есть, в итоге получалось не совсем формирование на лету, а выбор из кучи заранее сформированных
"Алла Савельева" написал:а какую бизнес-задачу Вы хотите решить таким образом?
Мы решали следующую задачу: для подбора персонала заполняются некоторые поля в карточке вакансии. На основании этих полей хотелось построить динамический фильтр в разделе Контакты, чтобы пользователи могли его дополнить/изменить и выбрать кандидатов
Так и не решили, кстати - пришлось пользователям изучать сложные универсальные механизмы фильтрации
"Алла Савельева" написал:а какую бизнес-задачу Вы хотите решить таким образом?
Необходимо хранить структуру каталога продуктов, хотели использовать статические группы т.к. продукты никак не привязаны к папкам, но статические группы не работают в 7.10. Так же структура весьма часто меняется, и изменения необходимо интегрировать из другой системы.
Можно реализовать некий справочник, который будет хранить структуру каталога продуктов. В каждом продукте добавить поле (назовем его [Каталог]), которое будет ссылаться на этот справочник и хранить принадлежность продукта к определенному каталогу.
На основании информации в поле [Каталог] настроить структуру динамических групп, какой угодно вложенности.
Конечно, такой способ не позволяет менять саму структуру каталога, но, как возможный вариант, считаю имеет право на жизнь.
Опять таки, у пользователя при необходимости будет возможность отфильтровать какие продукты к какому каталогу относятся.
А попробуйте реализовать эту функциональность с помощью статических групп в продуктах.
Группа = каталог (название группы - это название каталога), а продукт, который принадлежит каталогу входит в группу.
Если настроить импорт записей соответственно, то получится менять структуру автоматически.
Если появляется новый каталог, то добавляется новая статическая группа, в которую добавляются нужные продукты.
Из плюсов такого подхода: возможность хранения каталога в виде иерархического списка сколько угодно уровней вложенности.
Таким образом в Bpm'online для этого уже все реализовано, остается только вопрос в реализации импорта, а это фактически запись нужных данных в нужные таблицы :wink:
Небольшая поправка, если у Вас продукт bpm'online sales enterprise 7.10.1, тогда статических групп у Вас нет (они есть только в продукте bpm'online marketing), а вместо них есть тэги, о которых писал Владимир.
Добрый день. Если я копирую процесс (кнопка "Копировать диаграмму") который находится в пакете "MyPackage", то копия создается в пакете "Custom". Даже если в системной настройке CurrentPackageId установлен "MyPackage".
Является ли данное поведение корректным?
И есть ли возможность при создании копии указывать в какой пакет создавать эту копию?
Версия 7.10.0.1742
В новой диаграмме, которая создалась после копирования, нужно перейти на закладку Settings (Настройки) и в поле Package (Пакет) указать нужное значение (см. прикрепленный файл).
Нюанс со сменой пакетов может заключаться в потере данных, на которые завязаны элементы БП, так как в пакете, отличном от пакета копируемой диаграммы, могут отсутствовать эти данные.
Насчет корректности такого поведения системы (копирования в Custom). Логично копировать в тот пакет, который указан пользовательским. Вы пишите, что сменили значение настройки CurrentPackageId, попробуйте изменить значение настройки CustomPackageUId, после вылогиниться и потом зайти и проверить, куда будет скопирована диаграмма.
"Алла Савельева" написал:В новой диаграмме, которая создалась после копирования, нужно перейти на закладку Settings (Настройки) и в поле Package (Пакет) указать нужное значение (см. прикрепленный файл).
При разработке мы так же меняем системную настройку Maintainer, по этому изменение пакета к которому относится диаграмма оказывается достаточно сложным процессом:
"Алла Савельева" написал:
...
попробуйте изменить значение настройки CustomPackageUId
...
Спасибо за подсказку, действительно, после того как изменил эту настройку копия процесса начала создаваться в нужном пакете.
В документации нигде не нашел про существование этой настройки...
Просьба к сотрудникам Террасофт:
Может стоит указать об этой особенности копирования диаграмм в документации или исправить код который смотрит на CustomPackageUId вместо CurrentPackageId?