Комментарии 13
ммм. а зачем?
Не хотим, чтобы слой работы с данными уходил в пользовательский слой, но при этом хотим использовать виджеты Yii. Active Record не должно быть в Представлениях, иначе можно при рендере шаблона начать кидаться запросами в БД. Ладно, допустим $user->delete() разработчик писать не будет, но обратиться к какому-нибудь релейшену или цепочке?
Ну по хорошему все эти виджеты - они максимум для CRUD админки, причем простой. Если нужен нормальный фронт - то использовать апи. А уже в апи невозможно релейшн ошибочно загрузить
Согласен, все зависит от кейса и как устроен фронт.
Если мы используем шаблон Advanced от Yii2, который предлагает нам деление на Frontend/Backend, где это клиентское и админское приложения, которые мы строим со вьюхами (т.е. бэк отдает html) + JQuery, то как раз данная статья и подходит. Плюс мы пониманием, что использование данных виджетов уже подразумевает использование того же Bootstrap и JQuery.
Мы можем для упрощения разработки только админку оставить на этой схеме, а клиентскую часть сделать API + полноценный фронт React/Vue.
В последнем кейсе и жил проект, со слоевой архитектурой в которой Active Record не покидал Data Layer, а сервис с бизнес-логикой результат своей деятельности отдавал в виде неких DTO и их коллекций (в рамках Yii, те же дата провайдеры) и в зависимости от того, это API или админка по разному возвращал результат (json, рендер вьюхи и пр.).
иначе можно при рендере шаблона начать кидаться запросами в БД
Вас же не смущает, когда JavaScript во фронтенд-приложении несколько раз обращается к серверу во время рендеринга страницы, почему вдруг с серверным рендерингом той же верстки это проблема?
Потому что серверный процесс синхронный. Страница рендерится целиком. И результат запроса может влиять на те данные, которые уже отрендерились. Поэтому бизнес-логика должна обрабатывать до начала логики отображения.
Клиентское приложение асинхронное, оно работает с готовым рендером, модифицируя его с каждым запросом.
И результат запроса может влиять на те данные, которые уже отрендерились.
Если у вас данные меняются во время рендеринга, то это проблема архитектуры вашего приложения, а не ActiveRecord. Они у вас и с фронтенд-приложением будут меняться.
Поэтому бизнес-логика должна обрабатывать до начала логики отображения.
В случае фронтенд-приложения это правило не соблюдается. Подгрузка данных через JavaScript во время рендеринга по определению начинается после начала логики отображения этой страницы.
Клиентское приложение асинхронное, оно работает с готовым рендером, модифицируя его с каждым запросом.
Если вы переходите с главной страницы на страницу с некоторой таблицей, страница модифицируется практически вся. Даже в уже отрендеренный заголовок подгружается новая информация — количество непрочитанных уведомлений и т.д.
Серверный рендеринг тоже модифицирует готовый рендер, состоящий из пустой строки. То что на фронетнде он не пустой, а там есть несколько общих тегов типа <html>
, принципиально ничего не меняет.
некрофилия как она есть
Можно ли в методе ArticleRepository::findAllAsDataProvider заменить возвращаемый тип ActiveDataProvider на ArrayDataProvider?
https://www.yiiframework.com/doc/api/2.0/yii-data-arraydataprovider
А ссылки на github репозиторий у вас нету?
Суть в том, что мы работаем именно с ActiveDataProvider, который в свою очередь работает с Active Record и помогает нам формировать запросы (пагинация, сортировка, фильтрация и пр.).
Если нам не нужен Active Record, ничто не мешает создать и ArrayDataProvider (либо любой другой провайдер, ведь GridView ждёт интерфейс DataProviderInterface) и загрузить в него подготовленные объекты/модели, которые уже могут являться DTO. Но тогда мы берем на себя процесс получения этих данных (можно вообще не использовать AR и получить данные в виде массива из БД) и их подготовку (например, фильтрации по страницам, сортировку и пр.).
Зачем?) Это очень странно. В Yii2 есть ArrayDataProvider. Вам достаточно было отделить слой работы с моделью изменения от слоя чтения - аналог CQRS. Тогда бы у вас было меньше связанности. А так у вас может утекать какая-то логика в ваши DtoBuilder. Например, в User у нас есть статусы (активный, заблокирован). А в UI мам нужно только isActive чтобы показать что-то или скрыть. Тогда получается что вы эту проверку добавите в DtoBuilder. И как это тестировать?
Пойдём дальше, а что если к User нужно ещё добавить например список его комментариев из другого модуля? У вас уже будут совмещённые DtoBuilder или два билдера как-то объединять данные. А с разными репозиториями на чтение мы бы вызвали два репозитория, которые отдают нам две DTO: User и Comment и уже их бы передали в view.
Вы меня извините, на мой взгляд yii не очень хороший фреймворк, про виджеты я вообще молчу. Довелось повидать, вместо 2 строчек html целый виджет, и в чем его удобство извините меня???? А то что во вьюхе можно получить доступ к методам контроллера, потом попробуй найди эту логику. Смешно становится когда yii сравнивают с laravel или simfony.
Виджеты данных Yii2 и DTO