Rules: view logic
Правила: формы
Правила форм
-
Чтобы разместить несколько объектов в одной таблице сразу, ассистенту СЛЕДУЕТ объединить их в одну группу объектов с помощью скобок.
-
В секции
FORM ... ORDERSассистент ОБЯЗАН использовать только свойства формы, уже добавленные на форму через блокPROPERTIES.В
ORDERSассистент ОБЯЗАН указывать одно из:- имя свойства формы с его параметрами, если явный алиас не задан
- явный алиас свойства формы, если такой алиас был указан
Сырые выражения, объекты или свойства, не добавленные на форму, НЕ ДОЛЖНЫ помещаться в
ORDERS. -
Ассистент НЕ ДОЛЖЕН использовать
INPUTвнутри действий, добавленных непосредственно на форму черезPROPERTIES, если это действие не используется в обработчикеON CHANGE: значение встроенного класса вводится в редакторе свойства, изменение которого обрабатывается, поэтому вне обработчика изменения его негде отобразить. Исключение — значения файлов и цветов: они вводятся отдельным диалогом, и их МОЖНО запрашивать из любого действия формы.Чтобы запросить значения из кнопки, ассистенту СЛЕДУЕТ либо разместить вводимые свойства на самой форме (первичные свойства, в том числе локальные, в панели) и прочитать их в действии, либо открыть диалоговую форму, возвращающую введённые значения (
DIALOGс объектами, помеченнымиINPUT). -
Ассистент НЕ ДОЛЖЕН выводить на форму внутренние идентификаторы объектов, в том числе через свойства, значениями которых являются объекты: значение-объект отображается его внутренним идентификатором — числом, ничего не говорящим пользователю.
Вместо них ДОЛЖНЫ выводиться осмысленные примитивные или производные примитивные / текстовые свойства.
Самый частый случай — связь со статическим объектом класса-перечисления (
status = DATA Status (Project)): заголовок статического объекта платформа сама НЕ подставляет. На форму выводится композиция заголовка —captionStatus 'Статус' = caption(status(p)): запись через композицию уходит в связь, а не в заголовок статического объекта (см. правило 7), и при небольшом числе вариантов, как у перечислений, веб-клиент показывает её элементом выбора (группа кнопок / список / выпадающий список — по числу вариантов и длине заголовков). -
Объект
PANELпользовательского класса по умолчанию НЕ выбирается пользователем.Если такой объект должен выбираться пользователем (например, параметр фильтра, показанный на форме), ассистент ОБЯЗАН пометить отображаемое свойство этого объекта как
SELECTORв блокеPROPERTIES.Без
SELECTORячейка панели не открывает диалог выбора, и объект нельзя изменить. Ассистент НЕ ДОЛЖЕН предполагать, что ячейка панели редактируема по аналогии с редактированием в таблице. -
В блоке
PROPERTIESформы стиль параметров у свойства или действия, добавляемого на форму, ДОЛЖЕН соответствовать заголовку блока:- С заголовком с общими параметрами
PROPERTIES(p1, ..., pN)каждая запись ДОЛЖНА указываться только своим идентификатором — общие параметры связываются неявно. ЗаписьpropName(p1, ..., pN)после идентификатора — это ошибка разбора. - Без заголовка с общими параметрами (просто
PROPERTIES) каждая запись ДОЛЖНА нести явные скобки, напримерpropName(t)с параметрами, либоpropName()/actionName()для свойств и действий без параметров. Скобки ОБЯЗАТЕЛЬНЫ, даже когда параметров нет — пустые скобки всё равно ДОЛЖНЫ быть записаны. Голое имя без скобок — это ошибка разбора.
Ассистент НЕ ДОЛЖЕН смешивать два стиля в одном блоке и НЕ ДОЛЖЕН повторять общие параметры после имени свойства, когда используется заголовок с общими параметрами.
Это правило применяется только к записи, добавляемой на форму. Списки аргументов внутри опций вроде
ON CHANGE actionName(...),READONLYIF expr,BACKGROUND exprи т. д. — это обычные вызовы действий / выражения и ВСЕГДА используют явные параметры, независимо от заголовка блока.Записи, чьё выражение несёт запятую, не заключённую в собственные скобки, нужна форма, которую принимает этот блок: без заголовка общих параметров её пишут как
алиас = (выражение), потому что голое(выражение)— parse error; сPROPERTIES(o)запись остаётся использованием свойства и послеалиас =, выражение там не принимается вовсе, и единственное средство — именованное свойство, добавленное по идентификатору. - С заголовком с общими параметрами
-
Обработка изменения
CHANGEпо умолчанию у свойства, показанного на форме, выводится не из вида его выражения, а из пути записи: изменяемыми являются первичные свойства, оператор выбора и композиции изменяемых свойств — запись передаётся через композицию в нижележащее изменяемое свойство. Путь записи не виден в месте использования, поэтому ассистент НЕ ДОЛЖЕН предполагать, что вычисляемое на вид свойство нередактируемо.Внешне похожие записи при этом редактируются по-разному:
- композиция через объектную связь (
name(customer(o))) — пользователю предлагается выбрать связанный объект, и записывается связь (customer(o)); это обычный способ ввода; - атрибут самого объекта строки (
name(c)) — введённое значение записывается на месте, то есть объект переименовывается; - свойство статического объекта (
caption(st)) — запись уходит в хранимый заголовок статического объекта и живёт до очередной синхронизации базы данных с кодом (обычно при старте сервера), которая возвращает заголовок из кода.
Каждое свойство, показываемое только для чтения, ДОЛЖНО быть явно помечено
READONLY— во всех контекстах формы: не только в таблицах списочных форм, но и в панелях, диалогах, дашбордах и графиках. Когда только для чтения показывается весь блок, СЛЕДУЕТ помечать блок целиком (PROPERTIES(o) READONLY ...), а не каждую запись; пометка у отдельной записи остаётся для блоков, где часть записей предназначена для ввода. В контекстах просмотра и выбора каждая запись явно помечаетсяREADONLY, кроме записей, сознательно предназначенных для ввода. Явная пометка заодно документирует намерение для читателя кода. - композиция через объектную связь (
Правила потока управления (WAIT, NOWAIT)
-
Если не задана ни одна опция, платформа выбирает режим сама: оператор работает синхронно, когда форма открывается в модальном месте, когда модальна форма, из которой его открывают, или когда текущая сессия может использоваться дальше, — и асинхронно в остальных случаях.
Поэтому два одинаково выглядящих вызова могут вести себя по-разному. Там, где код после вызова зависит от того, что форма закрыта, или, наоборот, должен выполниться не дожидаясь, ассистент ОБЯЗАН сказать это явно — через
WAITилиNOWAITуSHOW, единственного оператора, синтаксис которого их принимает.У
DIALOGтакой опции нет: он синхронен, когда его результат используется, и отдан той же эвристике в остальных случаях. Когда диалог должен блокировать, ассистент добивается этого тем, что использует возвращаемое им значение.
Правила: дизайн форм
-
Эти правила дизайна НЕ покрывают модель раскладки
DESIGN— дерево контейнеров по умолчанию, модель flexboxfill/ выравнивания или идиомы контейнеров. Они дают лишь мета-советы по размещению. Перед написанием или изменением любогоDESIGNассистент ОБЯЗАН получить документациюForm_design; он НЕ ДОЛЖЕН полагаться на эти правила так, будто они описывают модель раскладки.Полные таблицы свойств компонентов всех видов (контейнеров, компонентов свойств и действий на форме, тулбаров, таблиц) содержатся в документации инструкции
DESIGN(DESIGN_statement). Задавая компоненту свойство, ассистент ОБЯЗАН сверить его имя и допустимые значения с этими таблицами, а НЕ ДОЛЖЕН угадывать их по аналогии. -
Ассистенту СЛЕДУЕТ задавать
DESIGNдля всех интерактивных форм, содержащих более четырёх свойств. -
Исключение: для тривиальной формы с одним-двумя объектами в режиме
GRIDи без других свойств, показанных в режимеPANEL, опусканиеDESIGNдопустимо. -
В
DESIGNассистенту СЛЕДУЕТ предпочитать перемещение контейнеровBOX(...)для таблиц в первую очередь.GRID(...)СЛЕДУЕТ использовать только при крайней необходимости. -
По возможности ассистенту СЛЕДУЕТ избегать дизайнов форм с более чем двумя таблицами по вертикали и более чем двумя таблицами по горизонтали.
-
Кастомные действия, добавляемые на грид-форму (смена статуса, генерация документов, массовые операции), ДОЛЖНЫ получать явный вид
TOOLBAR, напримерPROPERTIES(o) confirmDoc TOOLBAR. Действия по умолчанию имеют видPANEL, поэтому безTOOLBARкастомная кнопка рисуется отдельной группой под таблицей, а не в тулбаре грида рядом с предопределённымиNEW/EDIT/DELETE, которым платформа задает тот же видTOOLBAR, — то есть они делят с ней контейнерTOOLBAR, а неTOOLBARSYSTEM, на чем и промахиваетсяMOVEилиREMOVEне того контейнера. Виды свойств / действий:GRID,TOOLBAR,PANEL,POPUP. -
Свойство типа
TEXT, показанное колонкой грида, отрисовывается многострочной строкой высотой по умолчанию в четыре строки, снижая плотность списка. Такие колонки часто возникают из стандартных строковых свойств (lpad[TEXT, INTEGER, TEXT],substr[TEXT, INTEGER, INTEGER],trim[TEXT]и остальных): они, как правило, возвращаютTEXTнезависимо от классов аргументов, и конкатенация операнда классаTEXTс ограниченной строкой — тожеTEXT. На списочных формах ассистенту СЛЕДУЕТ вместо него выставлять значение, приведённое кSTRING[n]. Запись с приведением подчиняется правилам записей-выражений: в блокеPROPERTIESбез заголовка с общими параметрами и с явным алиасом (shortNote = STRING[100](note(o))). Голое приведение без алиаса, как и любое выражение внутри блока с заголовком общих параметровPROPERTIES(o), — ошибка разбора; там объявите именованное свойство с приведением и добавьте его по идентификатору. -
Для отображения данных ассистент ДОЛЖЕН сначала рассматривать стандартные виды представления группы объектов: таблицу, сводную таблицу с её диаграммами (
PIVOT), календарь (CALENDAR), карту (MAP). Пользовательское представление на компоненте React — контейнер вDESIGNс атрибутомcustom; только веб-клиент, десктоп-клиент отрисовывает обычное поддерево контейнера — применяется, когда требуется что-то сверх простой таблицы, простого календаря, простой диаграммы или сводной таблицы: канбан-доска, расписание, лента карточек, схема рассадки, перетаскивание, которого нет в стандартных видах, нестандартная раскладка или интерактивность. Перед созданием такого представления ассистент ОБЯЗАН получить документациюHow-to_Custom_React_views. -
FALSEдопустим в логических атрибутах блокаDESIGN—defaultComponent,activatedи подобных, — потому что их значения являются литералами, а не выражениями. Правило ядра, запрещающееFALSE, касается только выражений, и его НЕ ДОЛЖНО применять здесь, переписывая наNULL.
Правила: навигатор
- Папка, потомки которой должны появляться только при её
выборе, ОБЯЗАНА размещать этих потомков в другом окне, чем
сама папка (как правило,
WINDOW toolbar). В горизонтальном тулбаре, таком какSystem.root, папка, оставляющая потомков в своём окне, ничего не переключает — они показываются расплющенными рядом с ней, и выбор папки ничего не делает. Вертикальный тулбар, наоборот, отображает потомков из того же окна как вложенную группу под папкой, поэтому там отдельное окно не требуется.
Правила: отчёты
-
Прежде чем проектировать или править jrxml-шаблоны отчётов либо рассуждать о структуре отчёта или именовании шаблонов, ассистент ОБЯЗАН получить документацию
Report_design; он НЕ ДОЛЖЕН полагаться на эти правила как на справочник по формату шаблона или раскладке. -
Когда у формы нет независимых друг от друга групп объектов (все группы образуют единую цепочку зависимостей), по умолчанию создаётся ТОЛЬКО ОДИН jrxml-шаблон, называемый по каноническому имени формы (пространство имён + имя формы, каждая
.заменяется на_) БЕЗ постфикса — единственный потомок группы сливается с ней.Единственный шаблон получается именно из-за слияния, поэтому разработчик может его и отключить: опция
SUBREPORTу дочерней группы объектов не даёт слить её с родительской, и такой группе нужен собственный шаблон с постфиксом_<группа>. Поэтому ассистент ОБЯЗАН читать блоки объектов формы, а не только форму её зависимостей: линейной цепочке сSUBREPORTвнутри нужен не один шаблон, а отсутствие хотя бы одного молча отбрасывает их все (правило 3). -
Ассистент ОБЯЗАН именовать каждый шаблон точно: верхний отчёт — по каноническому имени формы без постфикса, каждый подотчёт — по каноническому имени формы плюс постфикс
_<группа>его первой непустой группы объектов. Если хоть у одного шаблона имя неверно (с точки зрения платформы не найден), платформа молча откатывается к полностью автоматическому дизайну на ВЕСЬ отчёт, без ошибки в логах, — то есть единственное несовпадение молча отбрасывает все кастомные шаблоны.
Правила: интернационализация
-
Ассистент ОБЯЗАН использовать файлы
*ResourceBundle.propertiesдля локализации UI.Значение внутри
{...}ДОЛЖНО трактоваться как ключ поиска, который lsFusion разрешает согласно текущей локали. -
Ассистент ОБЯЗАН сначала определить, используется ли обратный перевод в текущей области проекта.
Если используется, ассистент ОБЯЗАН продолжать его использовать в этой области и ОБЯЗАН следовать существующей политике проекта.
Ассистент ОБЯЗАН сохранять выбор идентификаторов согласованным с уже установленным там паттерном.
Ассистент НЕ ДОЛЖЕН вводить новую явную политику идентификаторов, если этого не просит пользователь.
-
Обратный перевод означает перевод в направлении, обратном обычной локализации UI: не
ключ -> локализованный текст, алокализованный текст -> ключ, и затем, при необходимости, в другую локаль.Если идентификаторы не заданы в коде явно, этим каноническим значением является сам текст на исходном языке. Это то, что платформа ИЩЕТ, а не то, что она хранит ключом: запись остается
id = исходный текст, а словарь, строящийся для поиска, — обратный,значение -> id. Ассистент, записавший бандл наоборот, получит записи, с которыми обратный перевод никогда не совпадет. -
Обратный перевод включается параметром запуска, задающим язык строковых литералов lsf-кода (
logics.lsfStrLiteralsLanguage). Когда он активен, ЛЮБОЙ обычный литерал'...'в позиции, допускающей локализацию, — в том числе литерал-константа в любом выражении, — совпавший со значением записи ResourceBundle, при разборе кода молча заменяется на её ключ{id}и в рантайме подставляется в текущей локали:'position'может стать'pozycja'. Ведущие и конечные пробелы в сопоставлении не участвуют и сохраняются вокруг подстановки; литерал пустой или состоящий из одних пробелов не заменяется никогда.Поэтому технические литералы — ключи JSON, URL, форматы, канонические имена, внешние идентификаторы — ассистент ОБЯЗАН записывать сырыми литералами
r'...', которые не участвуют ни в локализации, ни в обратном переводе. Обычные литералы'...'предназначены для текста, видимого пользователю.