Power Apps, Patch vs Update & Collect

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

Power Platform продвигает Power FX как свой собственный язык кода, и чтобы идти в ногу со временем, у него есть несколько способов делать одно и то же. Наиболее очевидным является работа с источниками данных и коллекциями (массивами). Как и большинство разработчиков с низким уровнем кода, я учился на практике, а не в процессе обучения, поэтому был удивлен, узнав, что существует не только Patch для обновления источников данных. Поэтому я решил изучить различные способы и найти лучший.

Ниже приведены все различные способы изменения массивов, на самом деле в Power Apps есть 3 различных массива, источники данных, коллекции и переменные. Все верно, вы можете сохранить массив в переменной, почему? Я понятия не имею.

Формула Описание Область применения
Патч Изменить / Создать Данные/колл
Обновить Заменить (как PUT) Данные/Колл
ОбновитьЕсли Изменение по условию Данные/Колл
SubmitForm Изменить / Создать Данные/Колл
Собрать Создать Все
ОчиститьСобрать Очистить & Создать Coll/Var
Удалить Удалить запись Данные/Колл
RemoveIf Удалить по условию Данные/Колл
таблица Создайте Var

Обратите внимание, что если вы собираете или очищаете переменную (Collect или ClearCollect), это работает, но также создает пустую коллекцию с тем же именем.

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

1. Изменение записи

Итак, если вы хотите обновить запись в источнике данных или коллекции (переменную обновить невозможно), у вас есть 4 варианта.

Patch(dummyData,
    LookUp(dummyData,ID=1)
,
    {Title:"Num1",number:1}
)
Войти в полноэкранный режим Выйти из полноэкранного режима
UpdateIf(dummyData,{Title:"Num1",number:1})
Войти в полноэкранный режим Выйти из полноэкранного режима
Update(dummyData,
    LookUp(dummyData,ID=1)
,
    {Title:"Num1",number:1}
,
    first
)
Войти в полноэкранный режим Выход из полноэкранного режима
SubmitForm(dummyDataForm)
Войти в полноэкранный режим Выход из полноэкранного режима

Самый простой способ — это SubmitForm (именно поэтому его пихают в шаблоны), но для меня ограничения макетов форм делают его не подходящим для большинства случаев (особенно сейчас, когда у нас есть обработка ошибок вне форм). Поэтому давайте проигнорируем его и посмотрим на остальное.

Как вы можете видеть, Update и Patch практически одинаковы, с той лишь разницей, которая есть между PATCH и PUT (Update заменяет запись, поэтому все поля должны быть включены, иначе они будут null). Поэтому я бы сказал, что Patch в большинстве случаев вытесняет Update.

Но есть еще UpdateIf, который не требует записи (сохраняет поиск/фильтр). Поэтому, на мой взгляд, он наиболее прост в использовании, если только у вас есть поле GUID, которое вы можете использовать (если вы не хотите делать массовые обновления одного и того же условия, для чего отлично подходит UpdateIf).

Только это не совсем верно, если у вас есть GUID, вы можете использовать Patch без поиска, так как нам не нужна полная запись для идентификации. Проверьте это:

Patch(dummyData,{ID=1},{Title:"Num1",number:1})
Войти в полноэкранный режим Выйти из полноэкранного режима

тоже работает, так что нам не нужен этот поиск.

**Bulk updates**
Вход в полноэкранный режим Выход из полноэкранного режима

Patch также может выполнять массовые обновления через коллекцию. Поэтому, если я вытащил источник данных в коллекцию (colData в примере ниже), обновил коллекцию, а затем исправил источник данных, Patch — это то, что нужно.

Patch(dataSource,ShowColumns(colData,"ID","Title"))
Вход в полноэкранный режим Выйти из полноэкранного режима

против

ForAll(colData,
    UpdateIf(dataSource,
        ID=ThisRecord.ID
    , 
        {Title:ThisRecord.Title,number:ThisRecord.number}
    )
)
Вход в полноэкранный режим Выход из полноэкранного режима

Я использую ShowColumns, потому что мы можем Patch поля readOnly, которые мы получаем из SharePoint Lists, хотя лучше было бы переместить это в Collect.

Patch также может смешивать и сопоставлять, поэтому если у вас есть коллекция или таблица с пустым GUID, он создаст запись для этой записи, но изменит другие записи.

colData=
    {ID:Blank(),number:34,Title:"Num34"}
,
    {ID:1, number:1,Title:"Num1.1"}
Вход в полноэкранный режим Выход из полноэкранного режима
Patch(dummyData,colData)
Войти в полноэкранный режим Выход из полноэкранного режима

Обновление может быть массовым, но только если соответствие установлено на All и в массиве нет GUID. UpdateIf будет, если есть несколько совпадений с условием.

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

2. Создание записи

Для создания записи у нас есть 3 основных способа (ClearCollect будет представлен как Collect):

Collect(dummyData,{Title:"Num1",number:1})
Войти в полноэкранный режим Выйти из полноэкранного режима
Patch(dummyData,
    Defaults(dummyData)
,
    {Title:"Num1",number:1}
)
Войти в полноэкранный режим Выйти из полноэкранного режима
Set(varDummyData,
    Table({Title:"Num1",number:1},{Title:"Num2",number:2})
)
Войти в полноэкранный режим Выход из полноэкранного режима

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

Поэтому Patch требует Defaults(dummyData), чтобы показать создание, а не модификацию, что дает Collect преимущество в простоте. Так что победа за Collect, или нет?

Вы когда-нибудь задавались вопросом, в чем смысл функции Table, кажется, что она полезна только для сохранения массивов в переменных. Но при использовании в Patch она может оказаться невероятно полезной. Используя Table, мы можем упростить Patch, создав однорядный массив.

Patch(dummyData,Table({Title:"Num1",number:1}))
Вход в полноэкранный режим Выйти из полноэкранного режима

Поэтому мы можем отказаться от Defaults(dummyData) и сделать все намного проще. Хотя Collect, вероятно, лучше, Patch очень близок, и у него есть преимущество — он не создает коллекцию, если она не существует, своего рода явная проверка, чтобы убедиться, что вы случайно не создадите новую коллекцию.

Массовые обновления

Показано функцией Table, вы можете Patch массово создавать данные (как указано выше, вы можете даже смешивать и сочетать с modify).

Patch(dummyData,
    Table(
        {Title:"Num1",number:1}
    ,
        {Title:"Num2",number:2}
    )
)
Вход в полноэкранный режим Выход из полноэкранного режима

Создает 2 новые записи (вы также можете изменить другую коллекцию вместо использования таблицы, просто убедитесь, что она не имеет поля GUID или, по крайней мере, Blank GUID).

Patch(dummyData,  
    Table(
        {ID:Blank(),Title:"Num1",number:1}
    ,
        {ID:Blank(),Title:"Num2",number:2}
    )
)
Вход в полноэкранный режим Выход из полноэкранного режима

Collect по своей сути является объемным, так как требует 2 массива, поэтому он снова проще, но интересно видеть, что Patch очень похож.

3. Удалить запись

Хорошая новость, удаление записи стало намного проще, всего лишь опции Remove и RemoveIf. Что является своего рода зеркальным отражением Update и UpdateIf.

Remove(dummyData,LookUp(dummyData,ID=1))
Вход в полноэкранный режим Выйти из полноэкранного режима

и

RemoveIf(dummyData,ID=1)
Войти в полноэкранный режим Выйти из полноэкранного режима

Итак, снова RemoveIf выглядит как лучший вариант, но вы можете использовать трюк Patch, чтобы сделать Remove немного проще:

Remove(dummyData,{ID:1})
Войти в полноэкранный режим Выйти из полноэкранного режима

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

Remove(dummyData,Gallery.Selected)
Войти в полноэкранный режим Выйти из полноэкранного режима

Массовые обновления

Оба могут массово удалять, используя таблицу или другую коллекцию для Remove:

Remove(dummyData,Table({ID:1},{ID:2}))
Войти в полноэкранный режим Выйти из полноэкранного режима

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

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

Для себя я взял за привычку Collect для коллекций, Patch для всех модификаций и созданий в источниках данных. Remove — для всего остального. Хотя я думаю, что сильные стороны Ifs (Update и Remove) означают, что в будущем я буду использовать их чаще.

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

Оцените статью
devanswers.ru
Добавить комментарий