Пару вопросов про виджеты

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Пару вопросов про виджеты

Сообщение Sereja3578 »

Всем привет.

Подскажите, есть у меня такая надобность, выводить в нескольких местах сертификаты пользователей, то есть есть пользователь у него есть профиль и есть сертификаты. Соответственно при этом страница редактирования профиля должна сразу содержать редактирование полей профиля и полей сертификата. Можно конечно сделать это, засунув все действия в один контроллер, но это криво. Поэтому я сделал вывод во вьюхе редактирования профиля виджета, в виде которого оформил сертификаты.

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

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

Если все действия связанные с моделью сертификатов держать в одном контроллере, а виджет использовать только для вывода, то вроде, как получается уже не так криво. Но просто интересно, можно ли как-то всю работу с моделью целиком повесить на виджет или это не возможно и концепция виджетов вообще такого не поддерживает?
winzza
Сообщения: 126
Зарегистрирован: 2015.06.11, 20:30

Re: Пару вопросов про виджеты

Сообщение winzza »

На сколько я помню, большие виджеты правильно в стиле MVC писать. Там же можете все как вам угодно и организовать.
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

winzza писал(а):На сколько я помню, большие виджеты правильно в стиле MVC писать. Там же можете все как вам угодно и организовать.
Извиняюсь, но я не особо понял на счет mvc в виджете, виджет ведь состоит из одного только контроллера в котором по сути только два основных метода init и run. В бест-практикс в доках написано:

Widgets are an object-oriented way of reusing view code.

When creating widgets, you should still follow the MVC pattern. In general, you should keep logic in widget classes and keep presentation in views.

Widgets should be designed to be self-contained. That is, when using a widget, you should be able to just drop it in a view without doing anything else. This could be tricky if a widget requires external resources, such as CSS, JavaScript, images, etc. Fortunately, Yii provides the support for asset bundles, which can be utilized to solve the problem.

When a widget contains view code only, it is very similar to a view. In fact, in this case, their only difference is that a widget is a redistributable class, while a view is just a plain PHP script that you would prefer to keep within your application.

Типа виджет должен быть законченной единицей, и вся логика должна быть в основном классе виджета.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение ElisDN »

В виджете оставьте только чтение и вывод, а действия по записи поместите в контроллеры. Например, форме входа в виджете указываем 'action' => ['/site/login'] и включаем Ajax-валидацию при необходимости.
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

Благодарю за ответы. С виджетом так и поступил, вынес все действия в контроллер, а виджет теперь только вьюху выводит.

Остался один вопрос нерешенным. Так как виджет выводит в другом представлении (в редактировании профиля) поля другой модели, я их решил красиво в модальное окно засунуть. Получается идут поля из другой модели, потом кнопка "Добавить сертификаты" и под ней выводится список уже созданных сертификатов в виде картинок и у каждого сертификата есть своя панелька с кнопками (редактировать, удалитьть, увеличить). С удалением, увеличением и созданием проблем нет. А вот с редактированием пока не понимаю, как сделать.

Обычно при редактировании, мы вызываем какой-то экшен, куда передаем id записи, или, что-то еще, не важно, и в этом экшене находим нужную нам запись, и в виде модели рендерим в представление, которое нам собственно и возвращается. А тут как быть, если нужно не на другую страницу переходить, а просто выводить форму редактирования в модальном окне на той же странице? По сути я хочу, чтобы при нажатии на кнопку редактирования, открывалось модальное окно с формой редактирования этой записи.

Во вложении, есть два скрина. На первом общий вид виджета уже вставленного в представление /profile/update, а на втором модальное окошко для создания сертификата. Модальное окошко для создания и кнопка "Добавить сертификат" рендерится сразу виджетом. В виджете в методе run просто передается в представление модель Certificate. Действия создания и удаления, как и советовали вынес в отдельный контроллер.

Скриншот1:
https://cloud.mail.ru/public/HcwY/Qni66ShvA

Скриншот2:
https://cloud.mail.ru/public/9ZLc/gC4TEfNQ5
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

Стоп. Что-то я туплю похоже. Обычным же ajax запросом можно сделать вроде. Сегодня попробую, отпишусь)
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

Да, оказалось не сложно. Нужно просто к кнопке редактирования (которая должна открывать модальное окно с формой редактирования), добавить, например data атрибут (data-certificate-id), по клику по этой ссылке, брать значение этого атрибута и передавать пост запросом через аякс в нужный экшен, там находить нужную модель, рендерить ее в представление, как положенно и потом среди ответа в функции success, в ajax, методом find искать нужну. часть и подставлять в модальное окно.

Пока только небольшой баг остался. При вставке контента ajax запросом, картинка в preview не отображается почему-то, а поле dropzone растягивается на пол страницы. Для загрузки картинок пользуюсь плагином krajee FileInput.
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

Что-то я погорячился с простотой этой затеи) При загрузке контента ajax, получается, что все плагины не работают. У меня в форме, которую я аяксом вставляю в модальное окно, подключены плагины - datepiker и fileinput. После подгрузки этой формы в модальное окно, плагины не пашут, так как подгруженная аяксом структура формы, для подгруженных ранее скриптов и стилей типа еще не существует. И даже если повторно тупо подгружать скрипты в аяксе, находя их на странице через append, все равно не получается.

Как тут можно быть? Или может вся затея с аяксом не подходит?

Сейчас принцип такой -

На странице есть заранее подготовленное модальное окно. При нажатии на кнопку редактирования, аяксом отправляется пост запрос к экшену certificates/update/57, где 57 собственно номер сертификата. В ответе, в функции success мы получаем то что нам возвращает функция рендера, в методе update. В этом ответе я нахожу форму и вставляю ее в тело модального окна.
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

Честно говоря, толкового решения проблемы я так и не нашел. Решил пока повторной загрузкой стилей и скриптов через тот же ajax, но это бед практик. Раньше я уже решал подобную проблему, но там было проще, я обработчик вешал то ли по клику на родительский элемент, то ли по первому наведению, а не при загрузке документа.

Что-то мне подсказывает, что пора изобретать какой-то автозагрузчик js, а то проблема со скриптами в контенте загруженном ajax уже не нова)
alexnew2000
Сообщения: 104
Зарегистрирован: 2015.10.04, 09:47

Re: Пару вопросов про виджеты

Сообщение alexnew2000 »

Sereja3578 писал(а):- datepiker и fileinput.
Иницируйте плагины после создания (показа) содержимого модального окна. Можно повесить на келлбек ajax )
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение rak »

да есть же renderAjax, в чем проблема?
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

alexnew2000 писал(а):
Sereja3578 писал(а):- datepiker и fileinput.
Иницируйте плагины после создания (показа) содержимого модального окна. Можно повесить на келлбек ajax )
Возможно это действительно более правильный вариант, так как вроде не нужно второй раз грузить скрипты. Правда, придется тогда разбирать ответ, для каждой его нужной части инициализировать нужные плагины, а потом все склеивать и отправлять) Но по сути это лучше чем грузить кучу скриптов заново.
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

rak писал(а):да есть же renderAjax, в чем проблема?
Вот за это спасибо) Я не знал, что есть такая полезная фишка. Точнее знал, что есть, но как работает не знал.

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

Но опять же, это все та же повторная загрузка пачки скриптов.

В предыдущем коменте посоветовали инициализировать нужные аплагины перед вставкой ajax контента. О минусах тоже упомянул.
alexnew2000
Сообщения: 104
Зарегистрирован: 2015.10.04, 09:47

Re: Пару вопросов про виджеты

Сообщение alexnew2000 »

Sereja3578 писал(а):....
В предыдущем коменте посоветовали инициализировать нужные аплагины перед вставкой ajax контента. ...
Извините, но не перед вставкой ajax контента, а после вставки контента.
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

alexnew2000 писал(а):
Sereja3578 писал(а):....
В предыдущем коменте посоветовали инициализировать нужные аплагины перед вставкой ajax контента. ...
Извините, но не перед вставкой ajax контента, а после вставки контента.
Это я не правильно написал, я имел ввиду после вставки, как вы и сказали на колбеке, например на complete.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Пару вопросов про виджеты

Сообщение Loveorigami »

Да, через renderAjax надо.
Работал в свое время с модальными окнами. Написал более менее стабильный виджет.
https://github.com/loveorigami/yii2-modal-ajax

Использую во всех своих админках (в гриде, во формах при добавлении нового элемента в селект, если таковой не присутсвует, формы настроек под каждый модуль, подгрузить форму или данные из action и т.п.).
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Пару вопросов про виджеты

Сообщение Sereja3578 »

В общем всем спасибо за ценные советы)

Пришел к такому выводу:

1. Если не хотите повторно грузить скрипты на страницу, то используйте метод, который посоветовал alexnew2000:

В ajax, после вставки на страницу контента, в колбеке, напривер в complete, просто заново инициализируйте плагины. В некоторых местах понадобятся дополнительные телодвижения, чтобы настроить эти плагины, например для плагина загрузки картинок, чтобы превью выводить, нужно в js передать название картинки, потом сформировать саму картинку и указать, как оьычно в настройках плагина. Но зато такой способ не замедляет работу скрипта.

2. Если скорость не особо важна, то можно сделать как посоветовал rak и, воспользоваться в контроллере методом renderAjax, и просто вставлять целиком весь ответ ajax куда нужно, при этом все скрипты будут повторно загружены.
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: Пару вопросов про виджеты

Сообщение maleks »

Sereja3578 писал(а): 2. Если скорость не особо важна, то можно сделать как посоветовал rak и, воспользоваться в контроллере методом renderAjax, и просто вставлять целиком весь ответ ajax куда нужно, при этом все скрипты будут повторно загружены.
Они не будут повторно загружены, браузер кеширует.
Yii2 universal module sceleton - for basic and advanced templates
Ответить