Search
Write a publication
Pull to refresh
5
0
Send message

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

Спасибо за такой развернутый комментарий! Согласен со всем, что написали, но хотел бы прояснить пару моментов:

Непосредственное нахардкоживание late final во вьюмоделях может означать только одно - что нам делать, когда придёт время тестов. И честно, не увидел в readme пакета и не услышал в статье ни одного слова о тестировании: как и возможно ли?

Пока что не реализовывал библиотеку, предназначенную для тестов, но наличие late final не должно ничему помешать. Я обязательно обновлю readme, когда решу, каким способом будет наиболее удобно тестировать.

Далее, примеры счётчиков настолько заезженные и банальные, что не отражают ровным счётом ничего и плохо пахнут. В противовес вашему примеру, пример на ValueNotifier(соблюдая именования и стиль):

Да, понимаю, пример неудачный, но хотел предоставить одновременно информативный и не занудный для начала пример. Более подробный (и, на мой взгляд, интересный пример) - форма регистрации + исходный код beholder_form. Действительно показывает, насколько лаконичные и мощные получаются решения.

Пожалуй это самое нелепое обвинение в сторону Riverpod. Начну с того, что StateNotifier уже устаревшая концепция. Используйте (Async)NotifierProvider. И комбинируйте состояния ровно также, как вы это делаете в случае с вашей библиотекой (ваш последний пример не ясен, возможно он содержит ошибку в именовании SearchUsersViewModel|UsersViewModel):

Ошибку поправил, а про NotifierProvider не знал, работал с riverpod'ом еще 1-ой версии. Виноват, что не проверил :)

Почему у меня не вышло с riverpod:
Началось все с формы из 3 полей. Потом проект разросся, и форм стало много. Чтобы не получать по 4 autocomplete'а на firstNameFieldProvider, я начал их класть в static классы - стало неудобно, часть провайдеров лежала в глобальном неймспейсе, часть - в классах. После этого я решил переиспользовать логику форм, но провайдеры на то и статические - много инстансов не создашь. Пришлось абсолютно все сносить и переписывать на StateNotifier (но, насколько помню, решение все равно получилось некрасивым - либо вследствие отсутствия опыта, либо из-за неуклюжести riverpod'а).

copyWith используется, когда модели являются иммутабельными и стейт-менеджер основан на сравнении hashcode для обновления состояния. Как в этом плане работает beholder? Если он основан на мутабельном состоянии, то как избежать лишних перестроек, когда данные на самом деле не изменились, но их присвоение произошло?

Каждый observable принимает equals; по умолчанию - это сравнение (== ). Значения observable на самом деле иммутабельные - разработчик переприсваивает value отдельных observable также, как BLoC переприсваивает state. Вот и получается, что в BLoC тебе нужно определять стейт целиком, а в beholder - по кусочкам - без нужды в copyWith.

AsyncStateAsyncValueResult.guard - это всё мне что-то очень сильно напоминает на подход в R..?, ну ладно, окей.

С AsyncState была опечатка, должен быть AsyncValue.
Действительно, мне очень понравилось то, как был сделан этот union в riverpod - очень емкое и универсальное средство для описания асинхронных состояний.

Возможно, напишу статью по внутреннему алгоритму или какой-нибудь туториал с боевым use-case'ом. Очень ценные у Вас советы, еще раз - спасибо!

Можете написать тесты и попробовать сломать алгоритм. Буду рад :D

Думаю, так будет гораздо продуктивнее. Можете писать мне в ЛС

Я хожу по дереву от измененных рутов. Если дохожу до хоть одного конечного обзервера (не-computed), то начинаю идти от него и запрашивать обновления.

Если я не ошибаюсь, doubt состояние не нужно в моем алгоритме. Т.к. проход осуществляется в 2 этапа: от рута к листьям, а потом от листьев к руту. Я наверняка знаю, какие узлы должны быть обновлены

Хм, я понял, о чем вы. Мой "doubt" реализован в виде кэша в Unit Of Work - если computed'а там нет, то он считается состоянием "doubt".

Это вшито в сам state, который computed использует под капотом.

Посмотрите реализацию алгоритма - она укладывается в одном файле из 200 строк. Если знаете, как улучшить, буду рад PR'у.

Если значение computed'а не слушается в данный момент, он не ребилдится.

Возможно, я неправильно выразился - изменение state'ов всегда собирается в "кучу", а обновление computed 'ов выполняется в следующем микротаске.

Но я бы отнес это к implementation detail, потому как вызов value на computed спровоцирует моментальный rebuild.

Information

Rating
Does not participate
Registered
Activity