Модель состояния для MVC

04.08.22

Разработка - Работа с интерфейсом

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

Скачать исходный код

Наименование Файл Версия Размер
Модель состояния для MVC - демо
.dt 121,28Mb
3
.dt 1.0.0.3 121,28Mb 3 Скачать
Модель состояния для MVC - конфигурация для обновления
.cf 98,62Kb
1
.cf 1.0.0.3 98,62Kb 1 Скачать

Модель состояния для MVC


Оглавление

Введение

Ретроспектива

Истоки и предпосылки нового решения

MVC и модель состояния

Концепция

Цикл расчета параметров

Цикл расчета состояния формы

Хранилище состояния

Модель данных

DSL для Модели состояния

Модель объекта и модель формы

Работа с параметрами состояния

Объект и контекст

Топологический порядок расчета

Нарушение порядка расчета

Изменение топологии расчета

Окончание расчета

Расчет параметров

Топологическая зависимость параметров

Выражение результата расчета

Расчет параметров ссылочного типа

Параметризация свойств параметров

Параметризация свойств связей

Расчет элементов формы

Зависимости элементов формы от параметров

Функция состояния

Выражение для заданного свойства

Параметры связей

Обработка события «ПриИзменении»

Работа с формой

Переключение контекста клиент/сервер

История выбора и проверка значения

Проверка заполнения и очистка данных

Слабая связь

Обработчики событий формы

Внедрение подсистемы

Модель объекта

Модель формы

Примеры

Модель заявки на расходование ДС: внешние и внутренние расчеты

Отображение валют

Заключение

Поставка

 

Введение

Ретроспектива

Решение задачи реализации шаблона MVC на 1С – весьма не тривиальная задача оказалась для меня. Здесь нужно было пройти определенный путь от 37. «похожее пробовал, но отказался: слишком сложный код у меня получался», до – да, это действительно работает. И секрет здесь в том, что нужно пробовать снова и снова, пока не будет найдено решение :)

Представленное решение является эволюционным развитием идеи реализации MVC на 1С. Ниже представлен список моих статей на эту тему. Возможно вам будет интересно увидеть в кратком изложении все варианты решения, которые я прошел и где нахожусь теперь.

Программирование интерфейсов в 1С или паттерн MVC для 1С (2012 год)

Выделение единой функции отображения УстановитьВидимостьДоступность, все события ПриИзменении транслировать в объект.

Шаблон MVC для управляемого интерфейса (2018 год) 

Формализация зависимостей в виде графа зависимостей, расчет реквизитов объекта по изменениям. Отображение формы в единой процедуре как в предыдущей публикации.

Управление состоянием формы через конечный автомат (2018 год)

Декларативное описание зависимостей элементов формы от параметров. Параметры могут ссылаться как на реквизиты объекта/формы, так и на значения в хранилище значений параметров.

Хотя в целом подсистема реализована независимо от подсистемы расчета реквизитов объекта, существует возможность совместного использования с предыдущим решением.

Управление состоянием для шаблона MVC и работы с данными объекта (2020 год)

Решение, в котором объединены два предыдущих: для расчета реквизитов объекта и для расчета состояния формы. Теперь используется одна база параметров для объекта и формы. В контексте модуля используются только та часть параметров, которая относится к объекту, в контексте формы к параметрам объекта добавляются параметры формы.

Модель состояния (актуальное решение)

В этом решении добавлена параметризация свойств как самих параметров, так и элементов формы. Такая возможность позволяет описать не только зависимости между параметрами, но и определять значения свойств декларативным образом. Например можно задать значение свойства Видимость для элемента формы через выражение с использованием значений других параметров. Изменение же значения параметра, используемого в выражении свойства автоматически инициирует пересчет заданного свойства. Аналогично можно описать свойства самих параметров, такие как: Использование, ПроверкаЗаполнения и т.д.

Другой особенностью решения является декларативный способ задания самой модели зависимостей через использование DSL модели состояния. Последнее не принципиально для работы самой подсистемы, однако является приятным бонусом. Описать модель состояния можно и просто заполнив данные по: параметрам состояния, связям параметров, элементам формы, параметрам элементов и т.д. Однако с использованием DSL это сделать становится гораздо проще и понятнее.

Истоки и предпосылки нового решения

Как видно, тема реализации паттерна MVC на платформе 1С меня интересует уже достаточно давно. Вначале я полагал, что для MVC в платформе уже все есть и для соответствия принципам шаблона необходима лишь определенная дисциплина в архитектуре кода (см. комментарий к первой статье 14. "порядок должен быть :)"). На практике оказалось, что архитектура, которая держится лишь на одной дисциплине, очень быстро начинает "плыть". Сложность получаемой архитектуры не позволяла эффективно сопровождать такую систему. Лучшая иллюстрация проблемы в комментариях к первой статье: 6. "MVC плохо применима в 1С", 35. "Процедура [отрисовки] разрастается в монстра".

К той же самой первой статье были и предложения по усовершенствованию решения, суть которых заключалась в реализации функции прорисовки для каждого элемента отдельно (см. 34. «В качестве параметра можно передавать элемент формы» , 35. «выполнять полную "перерисовку" тогда, когда требуется смена видимости одного элемента не практично») и использования автоматного программирования (см. 35. "я за автомат управления видом"). Эти идеи были реализованы в следующих решениях: реализация расчета зависимостей в объекте (см. "Шаблон MVC для управляемого интерфейса") и автомат для управления формой (см. "Управление состоянием формы через конечный автомат"). В поддержку правильности выбранного направления был комментарий к статье: 20. "Сложные формы ВСЕГДА делаются на конечных автоматах".

Для полноценной реализации MVC оставалось соединить эти два решения в одно. Такое решение было представлено в статье "Управление состоянием для шаблона MVC и работы с данными объекта". Тогда это была многообещающая реализация паттерна MVC: управление моделью и формой на основе декларативного описания связей. Несмотря на то, что изначально пример прилагался, последующие публикации должны были показать на более простых примерах как на практике можно решать проблему изменения состояния объекта и синхронизации этого состояния с отображением на форме (см. "Звездный рейтинг ***", "Рендеринг элементов управляемого интерфейса").

Однако в моей практике на долгие годы прижилось раздельное решение: отдельно состояние объекта и отдельно автомат для формы. В объединенном решении не хватало существенных деталей: оно оказалось достаточно сложным в использовании и не решало некоторых проблем.

Одна из нерешенных проблем: как описать изменение связей в объекте? Скажем если связи зависимостей внутри объекта сами могут быть результатом некоторого состояния? В текущем реализации это решается в коде, т.е. с нарушением принципа декларативности.

Вторая проблема: обеспечение чистоты данных, когда неиспользуемые реквизиты должны быть очищены (см. "Работа с данными заполнения"). Чистота данных влияет на алгоритмы и реализация MVC здесь не исключение.

Третья проблема: излишняя сложность. Большинство комментариев к последней статье были про сложность понимания и работы с подсистемой.

В новой версии подсистемы для этих проблем есть свои решения.

MVC и модель состояния

Концепция

За основу реализации подсистемы принят шаблон MVC. В контексте MVC код разделен на слои реализации: контроллер, модель объекта и модель формы.

Область контроллера – это область МодельСостояния в форме. Основная задача контроллера – подготовить список измененных параметров. Далее эти параметры передаются в модель объекта. Здесь происходит расчет по модели. И наконец, рассчитанные параметры передаются в модель формы для расчета её состояния.

Организация кода словем может быть следующей. Для контроллера – модуль формы, для модели объекта и модели формы – модуль модели состояния. Реализация модели объекта и формы возможна полностью на декларативном уровне, тогда и размещение кода не потребуется.

 

Рисунок 1. Диаграмма последовательности MVC

 

Цикл расчета параметров

Параметры, переданные в модель объекта, рассчитываются согласно определенному в модели порядку. Каждый параметр обрабатывается в цикле дважды: вначале определяется значение параметра, в следующий цикл по очереди – выполняется обработчик ПриИзменении.

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

 

Рисунок 2. Цикл расчета параметров состояния

 

Цикл расчета состояния формы

Результат расчета параметров передается в модель формы. Здесь формируется список элементов и их свойств, состояния которых зависят от рассчитанных параметров (см. раздел «Зависимости элементов формы от параметров»).

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

 

Рисунок 3. Цикл расчета элементов формы

 

Хранилище состояния

Подобно конфигурации 1С, метаданные модели где-то нужно сохранять. Для работы подсистемы необходимо хранить описание связей, настройки элементов формы, параметры состояния и их значения. Эти данные должны быть одинаково доступны как на клиенте, так и на сервере, т.е. к тому же должны синхронизироваться.

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

Как показали эксперименты, изменение хотя-бы одного реквизита формы приводит к синхронизации всех реквизитов формы между клиентом и сервером. Однако, если поменялась одна строка таблицы формы, то синхронизация происходит уже в оптимизированном виде - только по измененным данным. Т.о. организация хранения данных модели состояния в таблице формы оказывается самым оптимальным.

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

На практике оказалось эффективным использование для неизменяемых данных типы: Структура и Соответствие. Это не совсем иерархическая модель, как может показаться, но и не реляционная. Изменяемые данные, такие как значения параметров, хранятся в таблице объекта: для формы - в таблице формы, для объекта - в таблице значений. Для простоты будем отталкиваться от реляционной модели, которая отображена в структурные объекты.

Модель данных

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

 

Рисунок 4. Модель данных

 

Параметры состояния - параметры, значения которых полностью определяют состояние объекта. Сами параметры могут параметризироваться через функции, определяющие значения свойств параметров, таких как: Использование, ПроверкаЗаполнения, ЗаполнятьПоУмолчанию и т.д.

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

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

DSL для Модели состояния

Martinfowler.com/dsl.html 

https://russianblogs.com/article/13071310656/

habr.com/ru/post/239361/

https://www.jetbrains.com/ru-ru/mps/concepts/domain-specific-languages/

https://youtu.be/1BkElnlTBb4

Долго я шел к осознанию того, что DSL реально позволяет упростить задачу работы с подсистемой. Первое упоминание такой реализации (я так понимаю, что решение не выложено в общий доступ) было в комментарии 37. "Реализовали свой небольшой уо" [имеется в виду язык условного оформления] к статье "Управление состоянием формы через конечный автомат". Тогда я посчитал этот путь слишком сложным - для этого требуется разработать свой интерпретатор!

Однако успех нескольких решений с использованием текучего интерфейса убедил меня в выгодности создания DSL под конкретную задачу. Удивительно, но сложные задачи оказывается можно решать не только чисто алгоритмическим упрощением и абстракциями, но и посредством предметного языка. Такой язык может быть только декларативным, так как в противном случае мы просто получим набор инструкций для выполнения на компьютере и это уже не будет спецификой предметной области. Реализация абстрактного массива в одном из моих решений не имеет отложенного исполнения, однако она все-таки находится в области декларативного программирования (см. АТД Массив). Ничего не мешает мне в будущем добавить туда и отложенное исполнение, однако уже существующие алгоритмы с использованием АТД массивов не придется менять - в этом суть декларативного описания: описывается что нужно сделать, но не как. Еще одна очень удобная особенность декларативного подхода заключается в том, что при добавлении нового описания вам не потребуется искать место вставки своего кода в существующем алгоритме или как то его изменять для этого - вы просто добавляете новое описание и все! Другие примеры смотрите в моих решениях: Модель запроса, Модель распределения.

В текущем решении использован мой опыт по созданию библиотеки работы со схемой запроса. Недостатки такого решения в излишней избыточности кодирования и необходимости использовать переменные для хранения промежуточных результатов. Обратите внимание на то, что перечисленные недостатки являются принципиальными ограничениями для императивного программирования. Создание DSL под задачу реализации MVC на 1С позволяет убрать эти недостатки. Код с использованием DSL становится выразительным и компактным. Выразительным потому, что отражает цели исполнения предметной области MVC, а компактным потому, что не содержит инструкций исполнения. Последнее очень важно, так как встроенный язык 1С итак не поддерживает абстракции и достаточно беден для выражения алгоритмических решений, то это приводит к очень большому количеству кода. Сокрытие внутренней реализации движка DSL позволяет сосредоточится на задачах предметной области, не погружаясь в ограничения среды исполнения.

Для работы с настройкой подсистемы MVC был разработан DSL для Модели состояния.

Формальное описание DSL

[ПараметрСостояния][НаКлиенте]
    [Использование[
        [ИмяПараметра]|[Параметр]
            {Параметр}
            [Выражение]
        ]
    ]
    [Параметр][Слабая]
        [Использование[
            [ИмяПараметра]|[Параметр]
                {Параметр}
                [Выражение]
            ]
        ]
    {Параметр}
    [Выражение]

[ЭлементФормы][НаКлиенте]
    [Свойство(ИмяСвойства)]
        [Параметр]
        {Параметр}
        [Выражение]
    {Свойство}
    [Параметр]
    {Параметр}
    [ФункцияСостояния]

Модель объекта и модель формы

https://www.martinfowler.com/articles/languageWorkbench.html

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

Модель объекта, в отличии от Модели состояния - это уже работа с объектом, к которому применена Модель состояния. Модель состояния работает с построением описания метаданных модели объекта, а модель объекта непосредственно использует это описание в своей работе. Эта же идея заложена в паттерне Построитель.

Если бы не ограничение платформы, то работу с моделью объекта можно было реализовать через собственный DSL. Однако от этой идеи пришлось отказаться. Работа с моделями объекта и формы осуществляется в процедурном стиле, где обязательным параметром функций подсистемы является конфигурация модели. Это похоже на реализацию работы со схемой запроса, но в данном случае больше свободы в реализации, т.к. не используется внутренний объект платформы. Для работы с моделью объекта и моделью формы в подсистеме выделены два соответствующих модуля: РаботаСМодельюОбъекта, РаботаСМодельюФормы.

Использование для решения задач предметных областей DSL языков - это следующий уровень программирования. Фулер назвал его языко-ориентированным программированием. В приведенном эссе на эту тему Фулер говорит о различных задачах такого программирования: выделение абстракций и конфигураций. Как и в этом решении Модель объекта - для абстракция, а Модель состояния - это конфигурация.

Работа с параметрами состояния

Объект и контекст

Концептуально данные объекта отличаются от данных контекста тем, что объект задан в конфигураторе и его реквизиты сохраняются в базе данных. Данные контекста декларируются в контексте: в форме - в реквизитах, в модуле - в переменных.  Данные контекста тоже могут где-то сохранятся, однако это не будет работать автоматически. Для сохранения данных контекста потребуется написать код.

В контексте модели здесь все-таки ключевое не в моменте сохранения. Дело в том, что в зависимости от того, в контексте формы или в контексте модуля объекта применяется одна и таже модель объекта, путь к данным будет различаться. Так в контексте формы доступ к реквизитам объекта будет осуществляться через основной реквизит формы. Модель того же объекта в модуле будет обращаться к реквизитам объекта непосредственно. Единственно чем будет различаться режим работы модели объекта для контекста формы или модуля объекта - это наличием пути к данным объекта.

В контексте формы путь к данным объекта обязательно включает имя реквизита формы, в котором содержится объект, обычно это - "Объект". В контексте модуля объекта такого пути нет. Однако описание модели состояния при этом не должно быть различным, иначе потеряется смысл паттерна MVC: модель объекта не должна зависеть от интерфейса.

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

Другая ситуация возникает, когда в модели задействованы данные контекста. Для формы это будут реквизиты, а для модуля объекта - экспортируемые переменные модуля. Т.е. для действительно равнозначных моделей состояния и для формы и для модуля объекта необходимо добиться эквивалентности данных для двух контекстов.

Для контекстных данных также возникает задача их инициализации или чтения перед началом работы с объектом. А при сохранении объекта нужно также реализовать сохранение данных контекста.

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

Топологический порядок расчета

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

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

Нарушение порядка расчета

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

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

Изменение топологии расчета

Другая ситуация возможна, когда топология расчета определяется некоторым состоянием объекта. Такая ситуация обрабатывается подсистемой. Для описания таких изменений необходимо задать условия существования связей (признак связи параметра - Использование).

Пример параметров связей с условным использованием

    МодельСостояния.ПараметрСостояния("СчетКонтрагента")
        .Параметр("Отбор.Владелец", "Контрагент")
            .Использование()
                .Параметр("ЭтоВнутренняяОперация")
                .Выражение("НЕ Параметры.ЭтоВнутренняяОперация")
        .Параметр("Отбор.Владелец", "Организация")
            .Использование()
                .Параметр("ЭтоВнутренняяОперация")
                .Выражение("Параметры.ЭтоВнутренняяОперация")
    ;

 

Окончание расчета

Начальной точкой расчета модели являются измененные параметры. При расчете от начальных параметров точкой остановки могут быть условия:

  • следующий параметр не изменился

  • расчет следующего параметра невозможен из-за незаполненного обязательного параметра

  • был достигнут последний параметр последовательности расчетов.

Расчет параметров

Топологическая зависимость параметров

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

В DSL связи параметров задаются неявным образом через указание параметров, которые определяются значение зависимого параметра. Связи параметров определяются:

  • От параметров, определяющих значение текущего параметра

  • От параметров, определяющих значени параметризированных свойств параметров

  • От параметров, определяющих значения параметризированные свойств зависимостей между параметрами (связей)

Описание параметра ДоговорКонтрагента с зависимостями от параметров Организация, Контрагент

    МодельСостояния.ПараметрСостояния("ДоговорКонтрагента")
        .Использование("ЭтоВнешняяОперация")
        .Параметр("Отбор.Организация", "Организация")
        .Параметр("Отбор.Владелец", "Контрагент")
    ;

Выражение результата расчета

Обычно под расчетом параметра понимается некоторая формула. Например, Сумма = Цена * Количество. Такая формула задается выражением расчета.

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

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

Пример задания выражения для параметра состояния «ЭтоВнутренняяОперация»

    МодельСостояния.ПараметрСостояния("ЭтоВнутренняяОперация")
        .Параметр("ТипОперации")
        .Выражение("(Ложь
        | ИЛИ Параметры.ТипОперации = ПредопределенноеЗначение('Перечисление._ДемоТипыОперацийБюжетирование.ПеремещениеМеждуМестамиХраненияСредств')
        | ИЛИ Параметры.ТипОперации = ПредопределенноеЗначение('Перечисление._ДемоТипыОперацийБюжетирование.КонвертацияВалюты')
        |)")
    ;

Расчет параметров ссылочного типа

Вычисление конкретного значения – интуитивно понятно. Но что если нужно определить договор? Это уже ссылочное значение и по формуле его не вычислишь. Однако есть модель базы данных, в  которой определены связи данных. Согласно связям договор определяется через значение владельца и организации. Конечно это в общем случае не одно значение, а множество. Тогда что же здесь можно вычислить? Ну в частном случае это все-таки может быть одно значение, тогда результатом такого вычисления будет это значение. Если же значение не одно, то можно проверить, что выбранное значение соответствует ограничениям данных (связям) и тогда вычисленное значение будет либо прежнее, либо пустое.

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

Пример задания параметров связи для параметра состояния «ДоговорКонтрагента»

    МодельСостояния.ПараметрСостояния("ДоговорКонтрагента")
        .Параметр("Отбор.Организация", "Организация")
        .Параметр("Отбор.Владелец", "Контрагент")
    ;

 

Параметризация свойств параметров

Такие свойства параметров, как Использование, ПроверкаЗаполнения, ЗаполнятьПоУмолчанию – можно параметризировать. Например, использование параметра Контрагент и Договор контрагента имеет смысл только для внешних операций по заявке на движение денежных средств. Тогда для внутренних операций эти параметры должны быть исключены, а их значения должны быть очищены.

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

Параметризация свойства связи "Использование" через выражение (неявная)

    МодельСостояния.ПараметрСостояния("Контрагент")
        .Использование()
            .Параметр("ЭтоВнутренняяОперация")
            .Выражение("НЕ Параметры.ЭтоВнутренняяОперация")
    ;

 

Параметризация свойства связей "Использование" через параметр

    МодельСостояния.ПараметрСостояния("Контрагент")
        .Использование("ЭтоВнешняяОперация")
    ;

 

Параметризация свойств связей

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

Такая параметризация является тем механизмом, через который в модели состояния можно описать правила топологии зависимостей. Например, в заявке на операцию есть реквизит СчетКонтрагента с двойным подчинением Организации и Контрагенту. Для внутренних операций действует подчинение Организации, а для внешних – Контрагенту.

Параметризация свойства связей "Использование" через выражение

    ;//  Счет контрагента имеет двойное подчинение: для внутренней операции - владелец Организация, для внешней - Контрагент
    МодельСостояния.ПараметрСостояния("СчетКонтрагента")
        .Параметр("Отбор.Владелец", "Организация")
            .Использование()
                .Параметр("ЭтоВнутренняяОперация")
                .Выражение("Параметры.ЭтоВнутренняяОперация")
        .Параметр("Отбор.Владелец", "Контрагент")
            .Использование()
                .Параметр("ЭтоВнутренняяОперация")
                .Выражение("НЕ Параметры.ЭтоВнутренняяОперация")
    ;

 

Параметризация свойства связей "Использование" через параметр

    ;//  Счет контрагента имеет двойное подчинение: для внутренней операции - владелец Организация, для внешней - Контрагент
    МодельСостояния.ПараметрСостояния("СчетКонтрагента")
        .Параметр("Отбор.Владелец", "Организация")
            .Использование("ЭтоВнутренняяОперация")
        .Параметр("Отбор.Владелец", "Контрагент")
            .Использование("ЭтоВнешняяОперация")
    ;

Расчет элементов формы

Зависимости элементов формы от параметров

Элементы формы могут зависеть от параметров следующим образом:

  • По параметрам функции состояния

  • По выражению для заданного свойства

  • По настройке параметров связей

Функция состояния

Понятие функции состояния уже было рассмотрено в предыдущих моих публикациях (см. Управление состоянием формы через конечный автомат, Управление состоянием для шаблона MVC и работы с данными объекта). Здесь лишь дам краткое описание идеи.

Настройка элементов формы в платформе 1С может быть декларативная и алгоритмическая. В первом случае используется настройка условного оформления. Механизм условного оформления потенциально очень мощный механизм настройки формы, а в случае настройки строк таблиц – единственно возможный. Однако для настройки элементов формы он практически не используется и на это есть существенные причины:

  1. очень ограниченный список свойств элементов, поддерживаемый для настройки

  2. не все свойства из этого списка реально поддерживаются платформой для элементов, хотя ошибок нет

  3. механизм явно заточен под оформление строк таблиц

Если декларативный способ от 1С не подходит, то остается только алгоритмический. И здесь количество вариантов решения ничем не ограничено. В поисках лучшего решения я выделил несколько обобщенных вариантов:

  1. выделение главной функции по отображению

  2. выделение для разных групп элементов разных функций настройки и использование их комбинаций

  3. реализация главной функции под настройку переданного списка элементов

  4. улучшенная версия главной функции с учетом предыстории изменений в данных

  5. выделение для каждого элемента формы отдельной функции

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

На данный момент это уже устаревший вариант настройки элементов, однако он остается в подсистеме «Модель состояния» как универсальный механизм или для обратной совместимости :). Использовать функцию состояния имеет смысл для сложной настройки элементов, когда использование выражений для отдельных свойств нецелесообразно или более громоздко.

Описание элемента ЭтаФорма через использование функции состояния

    МодельСостояния.ЭлементФормы()
        .Параметр("Дата")
        .Параметр("Номер")
        .Параметр("Проведен")
        .Параметр("ПометкаУдаления")
        .Параметр("ЭтоНовый")
        .ФункцияСостояния()
    ;

 

Функция состояния для элемента ЭтаФорма в модуле модели состояния

Функция СвойстваЭлементаЭтаФорма(Свойства, Параметры) Экспорт
    Свойства.Вставить("Заголовок", СтрШаблон("Заявка на операцию %1 от %2. %3", Параметры.Номер, Параметры.Дата, 
            ?(Параметры.Проведен, "Проведен", 
                ?(Параметры.ПометкаУдаления, "Помечен на удаление", 
                    ?(Параметры.ЭтоНовый, "Новый", "Записан")
                )
            )
        )
    );
    Возврат Истина;
КонецФункции

Выражение для заданного свойства

Следующий способ настройки элементов, реализованный в «Модели состояния» – задание выражения для значений свойств элементов.

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

Еще можно провести аналогию с платформенным механизмом условного оформления. В УО используются условия и значения под эти условия. Результат по условному оформлению является сложением вычисленных условий и соответствующих значений свойств элемента. Если выделить одно свойство, то его значение будет определяться условием и сопоставленным значением. В подсистеме «Модель состояния» условие используется в выражении, а его результат используется для значения свойства.

Выражение для свойства «Заголовок» элемента ЭтаФорма

    МодельСостояния.ЭлементФормы()
        .Свойство("Заголовок")
            .Параметр("Дата")
            .Параметр("Номер")
            .Параметр("Проведен")
            .Параметр("ПометкаУдаления")
            .Параметр("ЭтоНовый")
            .Выражение("СтрШаблон('Заявка на операцию %1 от %2. %3', Параметры.Номер, Параметры.Дата, 
            |    ?(Параметры.Проведен, 'Проведен', 
            |        ?(Параметры.ПометкаУдаления, 'Помечен на удаление', 
            |            ?(Параметры.ЭтоНовый, 'Новый', 'Записан')
            |        )
            |    )
            |)
            |")
    ;

Параметры связей

В подсистеме заложена возможность декларативного описания связей. Связь может быть отключена и заменена на другую. Так, например, счет контрагента для внешней операции подчинен значению реквизита Контрагент. Для внутренней операции подчинение счета меняется со значения реквизита Контрагент на значение реквизита Организация.

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

В подсистеме “Модель состояния” пересчет параметров связей элемента происходит в зависимости от параметров состояния, которые непосредственно влияют на структуру связей этого элемента. Т.е. если изменилось значение параметра, определяющего значение параметризированного свойства другого параметра или связи зависимостей, то подсистема найдет по зависимому параметру все связанные с ним элементы формы (элементы ввода) и обновит у них состав параметров выбора и связей выбора.

Обработка события «ПриИзменении»

Может показаться, что событие «ПриИзменении» должно сработать сразу после изменения параметра. Однако здесь стоит задуматься о том, для чего вообще можно применять это событие.

Существующая система расчета параметров не позволяет нарушать порядок расчета. Если все-таки такое нарушение потребуется, то реализовать его можно через использования обработчика в событии «ПриИзменении».

Для нагладности возьмем пример с заполнением заявки на расход. Скажем в заявке требуется выбрать договор и валюту расчетов. Два этих параметра связаны: договор определяет валюту расчетов, а валюта должна соответствовать договору. В модели такая связь может быть описана только в одну сторону, например от договора к валюте. Если пользователь вначале выберет валюту, то было бы удобно, что система сама подберет договор. Последнее однако невозможно из-за нарушения порядка расчета. Однако такое ограничение легко обходится собственной реализацией обработчика события «ПриИзменении» для параметра «ВалютаРасчетов» (см. раздел Слабая связь).

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

Если в обработчике «ПриИзменении» меняются значения других параметров, то возникает необходимость в выполнении обработчиков события уже для них. Момент возникновения события для измененных параметров должен быть встроен в общую последовательность расчета – именно так можно обеспечить транзакционную целостность всех параметров перед выполнением обработчиков события для каждого параметра.

Немного другая ситуация возникает, если модель создается в режиме модуля вне интерфейса. В таком случае объект либо заполняется, либо изменяется – в обоих случаях модель объекта затем должна быть рассчитана. В таком случае изменение значений параметров является лишь отражением заполнения/изменения объекта. В процессе расчета такие параметры будут встроены в общую последовательность расчета, но реально расчитываться повторно уже не будут – для них будет вызван обработчик события «ПриИзменении» тогда, когда наступит их очередь.

И наконец, при полном расчете модели объекта все параметры будут расчитаны согласно последовательности расчета и для измененных параметров будут вызваны обработчики «ПриИзменении». Именно в этом и суть взаимодействия трех частей паттерна MVC: измененные параметры передаются в модель, затем втраиваются в общую последовательность расчета, изменяются и возможно порождают другие изменения, затем по окончании расчета рассчитанные параметры уже будут источником изменений в представлении (форме).

Работа с формой

Переключение контекста клиент/сервер

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

Часть параметров может быть рассчитана в контексте клиента, а часть - в контексте сервера. Например формулу суммы от цены и количества можно рассчитать на клиенте, а вот получить значение договора - нет.

Конечно трудно представить форму, в которой расчет всех параметров можно реализовать на клиенте. Если хотя бы один параметр требует контекста сервера, то получается любой расчет будет требовать контекста сервера? Если иметь в виду полный расчет, то так оно и будет. Однако у расчета есть начало (измененные параметры) и окончание – рассчитанные параметры (см. Выше «Окончание расчета»). Если в процессе расчета не встретился ни один параметр требующий контекста сервера, то весь расчет будет завершен в контексте клиента.

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

История выбора и проверка значения

В интерфейсе есть очень замечательная возможнось ускорение повторяющегося выбора через использование значений из истории. Этот платформенный механизм работает с учетом ограничений отбора, описанных в параметрах элементов: Связи параметров выбора, Параметры выбора. Однако у этого механизма есть существенный недостаток.

Дело в том, что история работает только по тем параметрам связей, которые являются реквизитами отбираемого значения (механизм истории работает только для ссылочных значений). Но связи могут быть не только по реквизитам. При использовании подсистемы Работа с данными выбора можно в связях использовать любые параметры.

Механизм исптории очень удобен для пользователей. Для корректной работы этого механизма в подсистеме необходимо либо использовать связи по реквизитам выбираемого объекта метаданных, либо выполнять проверку выбранного значения.

Проверка выбора регламентируется признаком элемента ПроверкаВыбора. Установка этого признака в элементе будет гарантировать, что выбранное значение соответствует условиям связей.

Проверка заполнения и очистка данных

В подсистеме заложен механизм проверки и очистки данных. Для каждого параметра эти признаки параметризируются.

Слабая связь

Признак слабой связи параметров – это техническое решение для возможности снятия ограничения выбора из интерфейса.

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

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

Однако использование слабой связи подразумевает существование собственного обработчика события ПриИзменении в форме. В этом обработчике необходимо реализовать код по заполнению связанного реквизита и выполнить передачу измененных реквизитов в подсистему модели состояния (см. пример в демо базе).

Обработчики событий формы

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

Событие формы

Обработчик

ПриСозданииНаСервере

-

ПриЧтенииНаСервере

ПриЧтенииВМоделиОбъектаНаСервере

ПослеЗаписиНаСервере

ПослеЗаписиВМоделиОбъектаНаСервере

НачалоВыбора%ИмяЭлемента%

НачалоВыбора

ПриАктивизацииСтроки%ИмяЭлемента%

ПриАктивизацииСтроки

ПриИзменении%ИмяЭлемента%

ПриИзменении

Таблица 1. Обработчики событий формы

Внедрение подсистемы

Модель объекта

Модель состояния для объекта должны быть проинициализирована перед использованием. Местом инициализации может быть любой модуль. Использование для этой цели модуля менеджера объекта – вполне практичный вариант.

В модуле менеджера объекта можно расположить код построения модели состояния. Пусть это будет функция МодельСостояния. Пример такой функции можно найти в демо базе для документа _ДемоЗаявкаНаОперацию. Тогда перед началом использования подсистемы нужно будет вызвать эту функцию.

 
 Конструктор модели состояния в модуле менеджера

 

Использование конструктора модели в обработчике заполнения

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    МодельОбъекта = Документы._ДемоЗаявкаНаОперацию.МодельСостояния(ЭтотОбъект).ПрименитьМодель();
    
    ФормаОплаты = Перечисления._ДемоВидыДенежныхСредств.Безналичные;
    ПриходРасход = Перечисления._ДемоПриходРасход.Расход;
    ВидОперации = Справочники._ДемоВидыОперацийБюджетирование.НайтиПоНаименованию("Расчеты с контрагентами", Истина);
    //ВидОперации = Справочники._ДемоВидыОперацийБюджетирование.НайтиПоНаименованию("Внутреннее перемещение", Истина);
    КурсРасчетов = 1;
    СуммаВзаиморасчетов = 100;
    
    РаботаСМодельюОбъектаКлиентСервер.ПриИзмененииПараметра(МодельОбъекта, "ФормаОплаты");
    РаботаСМодельюОбъектаКлиентСервер.ПриИзмененииПараметра(МодельОбъекта, "ПриходРасход");
    РаботаСМодельюОбъектаКлиентСервер.ПриИзмененииПараметра(МодельОбъекта, "ВидОперации");
    РаботаСМодельюОбъектаКлиентСервер.ПриИзмененииПараметра(МодельОбъекта, "КурсРасчетов");
    РаботаСМодельюОбъектаКлиентСервер.ПриИзмененииПараметра(МодельОбъекта, "СуммаВзаиморасчетов");
    
    РаботаСМодельюОбъектаКлиентСервер.Рассчитать(ЭтотОбъект, МодельОбъекта.ИзмененныеПараметры);
КонецПроцедуры

 

Модель формы

Если предполагается использовать интерфейсную часть модели, то в модуле формы необходимо:

  1. Добавить обязательные функции из области МодельСостояния

  2. В процедуре ПриСозданииНаСервере выполнить инициализацию модели состояния для объекта

  3. Добавить в модель параметры и настройку элементов формы

  4. Применить модель к форме

  5. Обновить форму (рендеринг)

 
 Создание и применение модели в обработчике ПриСозданииНаСервере

Примеры

Модель заявки на расходование ДС: внешние / внутренние расчеты

В качестве примера рассмотрим реализацию работы с документом «Демо: Заявка на операцию». Документ можно найти в пользовательском режиме в разделе «Демо: Модель состояния».

Документ моделирует работу заявку на расходование денежных средств. Расходование может быть внешним, когда оплата производится поставщику, или внутренней – деньги никуда не уходят, но могут быть перемещены между счетами организации.

Справочник банковских счетов имеет двойное подчинение: организации или контрагенту. Для внутренней операции это подчинение организации.

Для внутренней операции также действует правило: нет отражения по движениям операции.

Итого для интерфейса получаются следующие настройки для внешней операции:

  1. есть закладка Аналитики операции
  2. счет контрагента подчиняется контрагенту
  3. доступны для заполнения реквизиты контрагента: договор контрагента, контрагент расчетов, договор расчетов
  4. пересчет значений реквизитов: Счет контрагента

Для внутренней операции будут следующие настройки:

  1. нет закладок
  2. счет контрагента подчинен организации
  3. реквизиты контрагента скрыты
  4. пересчет значений реквизитов: Счет контрагента
  5. очистка реквизитов: Контрагент, Договор контрагента, Контрагент расчетов, Договор расчетов

С точки зрения настройки интерфейса здесь интересны только пункты 1 и 3. Пункт 2 и 5 – это не совсем про интерфейс. Изменение подчинения – это задача модели, но интерфейс здесь тоже участвует. При смене подчинения в элементе, связанном с реквизитом Счет контрагента должны измениться настройки параметров связей. Для внешней операции это связь Отбор.Владелец = Объект.Контрагент, а для внутренней – Отбор.Владелец = Объект.Организация. Вот так задано условие для смены владельца в модели:

    ;//  Счет контрагента имеет двойное подчинение: для внутренней операции - владелец Организация, для внешней - Контрагент
    МодельСостояния.ПараметрСостояния("СчетКонтрагента")
        .Использование()
            .Параметр("ФормаОплаты")
            .Выражение("Параметры.ФормаОплаты = ПредопределенноеЗначение('Перечисление._ДемоВидыДенежныхСредств.Безналичные')")
        .Параметр("Отбор.Владелец", "Организация")
            .Использование("ЭтоВнутренняяОперация")
        .Параметр("Отбор.Владелец", "Контрагент")
            .Использование("ЭтоВнешняяОперация")
    ;

Там же, в описании модели состояния, очистка данных моделируется через параметризацию признака Использование:

    МодельСостояния.ПараметрСостояния("ДоговорКонтрагента")
        .Использование("ЭтоВнешняяОперация")
        .Параметр("Отбор.Организация", "Организация")
        .Параметр("Отбор.Владелец", "Контрагент")
    ;

Непосредственно управление интерфейсом задается на уровне настройки элементов формы. Видимость элементов задается в зависимости от вида операции вот так:

    ;//  Управление отображением страниц через свойства: ОтображениеСтраниц, ТекущаяСтраница
    МодельСостояния.ЭлементФормы("Страницы")
        .Свойство("ОтображениеСтраниц")
            .Параметр("ЭтоВнешняяОперация")
            .Выражение("?(Параметры.ЭтоВнешняяОперация, ОтображениеСтраницФормы.ЗакладкиСверху, ОтображениеСтраницФормы.Нет)")
        .Свойство("ТекущаяСтраница")
            .Параметр("ЭтоВнешняяОперация")
            .Выражение("?(Параметры.ЭтоВнешняяОперация, Неопределено, 'СтраницаОсновныеРеквизиты')")
    ;//  Переключение видимости групп для внутренней операции и внешней
    МодельСостояния.ЭлементФормы("ГруппаКонвертацияРасчетов")
        .Свойство("Видимость")
            .Параметр("ЭтоВнутренняяОперация")
            .Выражение("Параметры.ЭтоВнутренняяОперация")
    ;
    МодельСостояния.ЭлементФормы("ГруппаРеквизитыКонтрагента")
        .Свойство("Видимость")
            .Параметр("ЭтоВнутренняяОперация")
            .Выражение("НЕ Параметры.ЭтоВнутренняяОперация")
    ;

Здесь для отображения страниц заданы выражения свойств ОтображениеСтраниц, ТекущаяСтраница. Отображение групп элементов, отвечающих за реквизиты внутренней и внешней операции регулируется выражением для признака Видимость.

Внешняя операция

 

Внутренняя операция

 

Отображение валют

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

Если валюты совпадают, то сумма расчетов скрывается. Также для внешней операции на закладке «Аналитики бюджета» есть колонки для суммы расчетов и суммы платежа. В заголовке колонок отображается валюта. Если валюта меняется, то меняется и заголовок. При одинаковых значениях валют колонка «Сумма расчетов» скрывается. Кроме того, когда сумма расчетов не видна появляется заголовок валюты расчетов.

Такому поведению системы соответствует следующее описание модели состояния формы:

    МодельСостояния.ЭлементФормы("ВалютаВзаиморасчетов")
        .Свойство("ТолькоПросмотр")
            .Параметр("ДоговорРасчетов")
            .Выражение("ЗначениеЗаполнено(Параметры.ДоговорРасчетов)")
        .Свойство("ПоложениеЗаголовка")
            .Параметр("ВалютаВзаиморасчетов")
            .Параметр("ВалютаДокумента")
            .Выражение("?(Параметры.ВалютаВзаиморасчетов = Параметры.ВалютаДокумента, ПоложениеЗаголовкаЭлементаФормы.Авто, ПоложениеЗаголовкаЭлементаФормы.Нет)")
    ;
    МодельСостояния.ЭлементФормы("СуммаВзаиморасчетов")
        .Свойство("Видимость")
            .Параметр("ВалютаВзаиморасчетов")
            .Параметр("ВалютаДокумента")
            .Выражение("Параметры.ВалютаВзаиморасчетов <> Параметры.ВалютаДокумента")
    ;
    МодельСостояния.ЭлементФормы("ДвиженияОперацииСуммаВзаиморасчетов").НаКлиенте()
        .Свойство("Заголовок")
            .Параметр("ВалютаВзаиморасчетов")
            .Выражение("?(ЗначениеЗаполнено(Параметры.ВалютаВзаиморасчетов), СтрШаблон('Сумма расчетов, %1', Параметры.ВалютаВзаиморасчетов), 'Сумма расчетов')")
        .Свойство("Видимость")
            .Параметр("ВалютаВзаиморасчетов")
            .Параметр("ВалютаДокумента")
            .Выражение("Параметры.ВалютаВзаиморасчетов <> Параметры.ВалютаДокумента")
    ;
    МодельСостояния.ЭлементФормы("ДвиженияОперацииСумма").НаКлиенте()
        .Свойство("Заголовок")
            .Параметр("ВалютаДокумента")
            .Выражение("?(ЗначениеЗаполнено(Параметры.ВалютаДокумента), СтрШаблон('Сумма платежа, %1', Параметры.ВалютаДокумента), 'Сумма платежа')")
    ;

Отображение суммы расчетов, если валюта разная

Отображение заголовка валюты расчетов, если валюта расчетов совпадает с валютой документа

Заключение

Вам была представлена новая версия подсистемы, реализующей паттерн MVC на платформе 1С. В этой версии используется единое пространство параметров модели объекта и формы. Для описания зависимостей используется модель состояния. Построение модели состояния реализовано в паттерне Построитель, когда конструирование объекта осуществляется посредством DSL.

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

Поставка

Метаданные подсистемы:

  • ОбщийМодуль.РаботаСМодельюОбъекта

  • ОбщийМодуль.РаботаСМодельюОбъектаКлиентСервер

  • ОбщийМодуль.РаботаСМодельюФормы

  • ОбщийМодуль.РаботаСМодельюФормыКлиентСервер

  • Обработка.МодельСостояния

Зависимости:

Решение выложено на github

Версия платформы 8.3.21.1302.

MVC элементы формы топологическая сортировка граф зависимостей приоритетная очередь

См. также

Богатый редактор картинок, хранимых в базе, с возможностью РИСОВАНИЯ. Редактор внешних файлов картинок. Объект, расширяющий возможности работы с картинками из встроенного языка (Три в одном) + Обработка «Стандартизация картинок»

Работа с интерфейсом Рабочее место Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Обработка предназначена для редактирования картинок в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Также обработка может быть использована из встроенного языка как объект для редактирования картинок. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Данная обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    61977    43    59    

81

[Расширения] Динамическое управление видимостью и доступностью элементов форм (УФ) (8.3.6+)

Работа с интерфейсом Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Механизм «Динамическое управление доступом к элементам форм объектов 1С8» предназначен для обеспечения возможности оперативного управления видимостью и доступностью элементов форм документов и справочников продуктов фирмы «1С» «1С:Предприятие 8». Решение универсальное, встраивается в любую конфигурацию с минимальными доработками, что позволяет без проблем обновлять типовые решения.

5000 руб.

14.01.2016    54608    16    21    

42

Управление дашбордами

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    16849    21    4    

35

Новогоднее оформление для 1С

Работа с интерфейсом Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Бесплатно (free)

Добавьте новогоднего настроения! Расширение создает декорацию в виде гирлянды на некоторых формах объектов.

27.12.2023    11044    758    elcoan    45    

106

Конструктор HTML, CSS и javascript

Инструментарий разработчика Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

10.04.2023    9812    153    acces969    31    

119

Табло очереди заказов на экран телевизора

WEB-интеграция Работа с интерфейсом Платформа 1С v8.3 1С:Розница 2 Платные (руб)

Связка из веб-приложения и расширения для 1С: Розница 2.3.

3600 руб.

29.04.2022    12233    1    5    

10

Модель распределения суммы по базе

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    7955    7    kalyaka    11    

44

Работа с данными заполнения

Инструментарий разработчика Платформа 1С v8.3 Россия Абонемент ($m)

Сложные объекты в зависимости от состояния могут характеризоваться различным набором реквизитов. При сохранении такого объекта в БД неизбежно часть реквизитов остаются исключенными. Если в таких реквизитах остаются данные, то это может привести к ошибкам как в алгоритмах, так и в интерпретации данных. С другой стороны, ключевые реквизиты, характеризующие объект, должны быть заполнены. В статье рассмотрена альтернативная реализация типового контроля заполнения данных.

1 стартмани

26.02.2022    8428    2    kalyaka    4    

15
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. alexander-lubich 26 04.04.23 16:07 Сейчас в теме
Где это применять?
Global__IT; +1
2. kalyaka 1057 04.04.23 22:24 Сейчас в теме
В статье я постарался свести весь свой опыт по реализации модели MVC на платформе 1С. Эта статья своего рода ретроспектива создания нового решения для MVC с использованием DSL. Материал достаточно сложный, согласен. Нужно понимать суть модели MVC и суть решения через создание собственного языка программирования (DSL).

Еще я хотел показать как можно решать задачи при помощи специализированных языков, созданных внутри платформы 1С. В своих решениях я применяю DSL для работы с запросами, для описания модели интерфеса и объекта, для описания модели распределения, работы с массивами.

Отвечая на Ваш вопрос, можно сказать, что область применения представленного решения - это, по сути, весь "фронтенд" на 1С в управляемом интерфейсе. А идеи статьи можно применять не только в интерфейсе.
+
3. Global__IT 270 08.04.24 01:45 Сейчас в теме
Не совсем понятно какой эффект это даёт. Скорость разработки? Снижение стоимости дальнейшей поддержки ? Проще говоря - зачем?
+
4. kalyaka 1057 08.04.24 08:22 Сейчас в теме
(3) Мне, как профессиональному разработчику, понятна тема. Но вновь прочитывая статью, чтобы вспомнить контекст, я понимаю, что тема то на самом деле сложная.

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

В "традиционном программировании" для такого поведения требуется прописать обработчики формы ПриИзменении, решить вопрос с контекстом выполнения Клиент или Сервер, вызвать алгоритм пересчета цены. Для работы сервиса также нужно знать какую процедуру пересчета нужно вызвать у документа. Т.е. разница в подходе: при MVC - подход не зависит от того, кто работает с объектом и есть ли у него интерфейс (возможно и не один), а традиционно - требуется знать внетреннее устройство объекта и подходы будут различаться для различных режимов работы. Ну и конечно количество кода при MVC будет меньше и точки изменения будут одинаковыяе для разных режимов работы.

Тут конечно можно возразить, что и при "традиционном" подходе можно вынести все процедуры обработчиков в общий модуль и вызвать их из разных режимов. Но даже в этом случае вам придется писать больше кода, т.к. потребуется некоторая "объвязка" для поддержки разных режимов вызова (интерактивный / система-система). Когда при использовании MVC все эти "объвязки" уже вынесены в отдельный фреймворк и разработчику требуется только встроиться в него.
+
Оставьте свое сообщение