WT. Практика (Mobile)
Платформа WTПрактикаСинтаксисБаза знаний
  • Приветствие
  • ОСНОВНОЙ
    • Урок 1. Hello World
    • Урок 2. Аутентификация пользователей в программе
    • Урок 3. Форма списка
    • Урок 4. Редактирование списка
    • Урок 5. Работа с JSON
    • Урок 6. Главный экран. Фильтры
    • Урок 7. Автоматическое обновление данных
    • Урок 8. Пользовательские настройки
    • Урок 9. Взаимодействие с другими приложениями и функциями телефона
  • КАСТОМИЗАЦИЯ
    • Урок 10. Кастомный элемент
Powered by GitBook
On this page
  • Построение объекта
  • Сохранение изменений
  1. ОСНОВНОЙ

Урок 5. Работа с JSON

Если вы прошли расширенные уроки, то можете смело переходить к разделу...

Работу с JSON будем рассматривать на примере карточки заказа, так как заказ имеет вложенные сущности и потенциально может иметь больше уровней вложенности. Теперь будет интересно увидеть, как изменится форма с использованием JSON-объекта.

Построение объекта

С формы заказа на сервер должен уходить JSON-объект подобного вида:

{
   "order_id":3,
   "client_id":7,
   "order_position":[
      {
         "order_position_id":1,
         "material_id":4,
         "quantity":25.00,
         "unit_price":200.00,
         "updated": true,
         "deleted": false
      },
      {
         "order_position_id":null,
         "material_id":2,
         "quantity":2.00,
         "unit_price":350.00,
         "updated": false,
         "deleted": false
      }
   ]
}

Так как JSON-объект представляет собой набор пар "ключ-значение", то нам необходимо создать структуру <Structure> типа Dictionary, которую присвоим в объект Variable:

TemplateOrderEdit.xml
<MyObject Name="OrderDictionaryVariable" Type="Variable" Assembly="SimpleControls" ChangeForm="False">
  <Value>
    <Structure Type="Dictionary">
      <Key Name=""></Key>
    </Structure>
  </Value>
</MyObject>

Обратите внимание, что у тэга <MyObject> стоит атрибут ChangeForm со значением False - этот объект вспомогательный, форма не должна его учитывать при проверке наличия изменений.

Добавим необходимые ключи в структуру и укажем источники данных:

<MyObject Name="OrderDictionaryVariable" Type="Variable" Assembly="SimpleControls" ChangeForm="False">
  <Value>
    <Structure Type="Dictionary">
      <Key Name="order_id">
        <DataTypeConvert Type="IntegerDataType">
          <Parameter Name="OrderId" Refresh="False" />
        </DataTypeConvert>
      </Key>
      <Key Name="client_id">
        <DataConnection SourceDataConnection="OrderPrimaryGetDataConnection" GetScalar="True" Refresh="False">
          <Fields>
            <Field Name="ClientId" />
          </Fields>
        </DataConnection>
      </Key>
      <Key Name="order_position">
        <Array>
          <Source>
            <DataConnection SourceDataConnection="OrderPositionConvertDataConnection" Refresh="False">
              <Fields>
                <Field Name="OrderPositionId" />
                <Field Name="MaterialId" />
                <Field Name="Quantity" />
                <Field Name="UnitPrice" />
                <Field Name="Updated" />
                <Field Name="Deleted" />
              </Fields>
            </DataConnection>
          </Source>
          <ToDictionary>
            <Key Name="order_position_id" Index="0" />
            <Key Name="material_id" Index="1" />
            <Key Name="quantity" Index="2" />
            <Key Name="unit_price" Index="3" />
            <Key Name="updated" Index="4" />
            <Key Name="deleted" Index="5" />
          </ToDictionary>
        </Array>
      </Key>
    </Structure>
  </Value>
</MyObject>

Для поля client_id из OrderPrimaryGetDataConnection необходимо получить одно единственное значение - для этого используем атрибут GetScalar со значением True.

Для поля order_position, содержащего массив объектов, используем конструкцию <Array> с преобразованием массива строк из ConvertDataConnection в массив словарей.

У тэгов <Parameter> и <DataConnection> появился атрибут Refresh, который определяет, будет ли обновляться значение у тэгов <Key> и <Array>, если изменится значение источника. Таким образом, значение объекта OrderDictionaryVariable не будет пересчитываться каждый раз, когда измениться какой-либо источник.

Для ручного пересчета OrderDictionaryVariable нужно использовать команду ValueSetCommand для вызова set-проперти Refresh у объекта Variable:

TemplateOrderEdit.xml
<Command Name="OrderDictionaryVariableRefreshValueSetCommand" Type="ValueSetCommand" Assembly="Commands">
  <Object Name="OrderDictionaryVariable">
    <Property Name="Refresh" />
  </Object>
</Command>

Чтобы словарь преобразовать к JSON-объекту, создадим команду типа SerializeToJsonCommand:

TemplateOrderEdit.xml
<Command Name="OrderDictionaryVariableSerializeToJsonCommand" Type="SerializeToJsonCommand" Assembly="Commands">
  <Variable>
    <Object Name="OrderDictionaryVariable" />
  </Variable>
</Command>

Команда SerializeToJsonCommand при формировании JSON-объекта преобразует все даты со временем к UTC относительно пользовательских настроек временной зоны.

Сохранение изменений

Добавьте кнопку сохранить, как делали на экране со списком ТМЦ.

Создадим SetDataConnection, который в параметре Model будет передавать на сервер сериализованный JSON-объект:

<DataConnection Name="OrderUpdateSetDataConnection" Type="SetDataConnection" Assembly="DataConnections">
  <Workflow Name="Template" />
  <SqlQueries>
    <SqlQuery Name="AppOrderSaveSqlQuery" Type="Update" />
  </SqlQueries>
  <Parameters>
    <Parameter NativeName="Model">
      <Value>
        <Command Name="OrderDictionaryVariableSerializeToJsonCommand" />
      </Value>
    </Parameter>
  </Parameters>
</DataConnection>

Где запрос будет иметь вид:

Template.xml
<SqlQuery Name="AppOrderSaveSqlQuery">
  <Text>
    SELECT template.order_save_from_app({Model}::json);
  </Text>
</SqlQuery>

Создадим последовательность команд SaveSequentialCommand, в которую добавим команды на построение JSON_объекта и команду передачи данных на сервер:

TemplateOrderEdit.xml
<Command Name="SaveSequentialCommand" Type="SequentialCommand" Assembly="Commands">
  <Commands>
    <Command Name="OrderDictionaryVariableRefreshValueSetCommand" />
    <Command Name="OrderDictionaryVariableSerializeToJsonCommand" />

    <Command Name="OrderUpdateSaveCommand" />
    <Command Name="UpdatedTrueValueSetCommand" />
  </Commands>
</Command>

Не забывайте про паттерн Updated.

Сохранение в базу

Реализуйте функцию template.order_save(json). Функция должна возвращать order_id, который необходимо отлавливать на форме TemplateOrderEdit.xml и писать в параметр OrderId.

Не забывайте про работу с датой со временем и временные зоны. В JSON-строке на сервер даты со временем придут в UTC. Для приведения времени во временную зону сервера используйте функцию public.convert_date_json(timestamp without time zone).

Last updated 1 month ago