Важные особенности работы с данными карточки через API
Важные особенности работы с данными карточки через API¶
Допустим, есть карточка.
Card card = ... ;
У неё есть строковая секция MyEntry и табличная MyTable. Для табличной секции возьмём первую строку.
CardSection myEntry = card.Sections["MyEntry"];
CardSection myTable = card.Sections["MyTable"];
CardRow myRow = myTable.Rows[0];
Есть несколько способов изменить поле MyField для этих секций.
-
Изменяем поле с оповещением об изменении через Fields. Если устанавливаемое значение отличается от того, что уже установлено в этом поле, то поле отмечается как изменённое и для него генерируются события об изменении (основным из них является FieldChanged, о других можно узнать из интерфейса Tessa.Cards.ICardFieldContainer).
myEntry.Fields["MyField"] = 42;
myRow.Fields["MyField"] = 42;
-
Такой способ особенно полезен на клиенте для уже отображённой на экране карточки (в расширениях CardUIExtension), чтобы контролы смогли узнать об изменениях и обновить выводимые ими значения.
-
В клиентских расширениях BeforeRequest на сохранение карточки Store использование такого подхода определяет, что изменённые поля попадут на сервер и действительно будут сохранены. Если карточка сохраняется первый раз, то они будут сохранены в любом случае.
-
Этот способ нельзя использовать в расширениях AfterRequest (клиентских и серверных) на загрузку карточки Get и на создание New, т.к. информация об изменениях в полях будет воспринята на клиенте так, будто бы изменения внёс пользователь. Поэтому вкладку с карточкой нельзя будет закрыть без сообщения “карточка изменена”, а при сохранении карточка уйдёт на сервер как изменённая.
-
-
Изменяем поле через dynamic. Это более удобный способ записи для п.1, в остальном он полностью аналогичен. Использовать его можно только на объекте Card.
card.DynamicEntries.MyEntry.MyField = 42;
card.DynamicTables.MyTable[0].MyField = 42;
-
Изменяем поле без оповещений об изменении. При этом поле не отмечается как изменённое и не выполняются события (FieldChanged и др.), посредством которых контролы могли бы обновить своё представление.
myEntry.RawFields["MyField"] = 42;
myRow["MyField"] = 42;
-
Этот способ полезен, если требуется изменить карточку на сервере в процессе сохранения карточки (где оповещение об изменении полей не имеет смысла).
-
Используйте этот способ, чтобы “обмануть” пользователя и подставить ему фиктивную информацию о полях при загрузке карточки Get или при создании карточки New (на клиенте или на сервере), в т.ч. и для заполнения виртуальных секций.
-
-
Изменяем поле напрямую в пакете карточки. Это аналог п.3, но менее удобный, хотя в некоторых очень редких случаях может использоваться для чуть большей производительности. Но не всегда, поэтому использовать этот подход не рекомендуется.
Dictionary<string, object> myEntryFields = myEntry.GetStorage().Get<Dictionary<string, object>>("Fields"); myEntryFields["MyField"] = 42;
Dictionary<string, object> myRowFields = myRow.GetStorage(); myRowFields["MyField"] = 42;
Для получения значений полей может использоваться любой из приведённых выше способов, и все они равнозначны. Способы “без оповещения” (3 и 4) чуть более производительны, но разницы с точки зрения выполняемого кода нет. Подключите using Tessa.Platform, чтобы код ниже выполнялся.
-
Fields
int magicNumber = myEntry.Fields.Get<int>("MyField");
int magicNumber = myRow.Fields.Get<int>("MyField");
-
Dynamic
int magicNumber = card.DynamicEntries.MyEntry.MyField;
int magicNumber = card.DynamicTables.MyTable[0].MyField;
-
RawFields
int magicNumber = myEntry.RawFields.Get<int>("MyField");
int magicNumber = myRow.Get<int>("MyField");
-
Напрямую в пакете
Dictionary<string, object> myEntryFields = myEntry.GetStorage().Get<Dictionary<string, object>>("Fields"); int magicNumber = myEntryFields.Get<int>("MyField");
Dictionary<string, object> myRowFields = myRow.GetStorage(); int magicNumber = myRowFields.Get<int>("MyField");