Пару вопросов про виджеты
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Пару вопросов про виджеты
Всем привет.
Подскажите, есть у меня такая надобность, выводить в нескольких местах сертификаты пользователей, то есть есть пользователь у него есть профиль и есть сертификаты. Соответственно при этом страница редактирования профиля должна сразу содержать редактирование полей профиля и полей сертификата. Можно конечно сделать это, засунув все действия в один контроллер, но это криво. Поэтому я сделал вывод во вьюхе редактирования профиля виджета, в виде которого оформил сертификаты.
То есть получается что виджет выводит кнопку добавления сертификатов, при нажатии на которую открывается форма с полями модели сертификата, при отправке формы соответственно создается сертификат, его создание прописано в самом виджете в методе run. Так же виджет выводит под кнопкой добавления сертификатов, все уже созданные сертификаты, (картинка, название и панель с кнопками - удалить, редактировать, увеличить). На сколько я понимаю, виджет может выполнять только одно действие, ну допустим можно сделать виджет для подписки на рассылку, с формой и отправкой оповещения, но больше одного действия добавить нельзя, так как в виджете нет экшенов. А тем не менее нужно выполнять для сертификатов такие действия, как редактирование и удаление.
Правильно ли я понимаю, что виджет может выполнять только одно какое-то действие? Если так, то может правильней сделать виджет просто для вывода сертификатов и модального окна с формой, а все действия, включая создание, удаление и редактирование вынести уже в контроллер? Просто как-то разбрасывать действия связанные с одной моделью (создание в виджете, а редактирование и удаление в отдельном контроллере) не хочется.
Если все действия связанные с моделью сертификатов держать в одном контроллере, а виджет использовать только для вывода, то вроде, как получается уже не так криво. Но просто интересно, можно ли как-то всю работу с моделью целиком повесить на виджет или это не возможно и концепция виджетов вообще такого не поддерживает?
Подскажите, есть у меня такая надобность, выводить в нескольких местах сертификаты пользователей, то есть есть пользователь у него есть профиль и есть сертификаты. Соответственно при этом страница редактирования профиля должна сразу содержать редактирование полей профиля и полей сертификата. Можно конечно сделать это, засунув все действия в один контроллер, но это криво. Поэтому я сделал вывод во вьюхе редактирования профиля виджета, в виде которого оформил сертификаты.
То есть получается что виджет выводит кнопку добавления сертификатов, при нажатии на которую открывается форма с полями модели сертификата, при отправке формы соответственно создается сертификат, его создание прописано в самом виджете в методе run. Так же виджет выводит под кнопкой добавления сертификатов, все уже созданные сертификаты, (картинка, название и панель с кнопками - удалить, редактировать, увеличить). На сколько я понимаю, виджет может выполнять только одно действие, ну допустим можно сделать виджет для подписки на рассылку, с формой и отправкой оповещения, но больше одного действия добавить нельзя, так как в виджете нет экшенов. А тем не менее нужно выполнять для сертификатов такие действия, как редактирование и удаление.
Правильно ли я понимаю, что виджет может выполнять только одно какое-то действие? Если так, то может правильней сделать виджет просто для вывода сертификатов и модального окна с формой, а все действия, включая создание, удаление и редактирование вынести уже в контроллер? Просто как-то разбрасывать действия связанные с одной моделью (создание в виджете, а редактирование и удаление в отдельном контроллере) не хочется.
Если все действия связанные с моделью сертификатов держать в одном контроллере, а виджет использовать только для вывода, то вроде, как получается уже не так криво. Но просто интересно, можно ли как-то всю работу с моделью целиком повесить на виджет или это не возможно и концепция виджетов вообще такого не поддерживает?
Re: Пару вопросов про виджеты
На сколько я помню, большие виджеты правильно в стиле MVC писать. Там же можете все как вам угодно и организовать.
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
Извиняюсь, но я не особо понял на счет mvc в виджете, виджет ведь состоит из одного только контроллера в котором по сути только два основных метода init и run. В бест-практикс в доках написано:winzza писал(а):На сколько я помню, большие виджеты правильно в стиле MVC писать. Там же можете все как вам угодно и организовать.
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.
Типа виджет должен быть законченной единицей, и вся логика должна быть в основном классе виджета.
Re: Пару вопросов про виджеты
В виджете оставьте только чтение и вывод, а действия по записи поместите в контроллеры. Например, форме входа в виджете указываем 'action' => ['/site/login'] и включаем Ajax-валидацию при необходимости.
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
Благодарю за ответы. С виджетом так и поступил, вынес все действия в контроллер, а виджет теперь только вьюху выводит.
Остался один вопрос нерешенным. Так как виджет выводит в другом представлении (в редактировании профиля) поля другой модели, я их решил красиво в модальное окно засунуть. Получается идут поля из другой модели, потом кнопка "Добавить сертификаты" и под ней выводится список уже созданных сертификатов в виде картинок и у каждого сертификата есть своя панелька с кнопками (редактировать, удалитьть, увеличить). С удалением, увеличением и созданием проблем нет. А вот с редактированием пока не понимаю, как сделать.
Обычно при редактировании, мы вызываем какой-то экшен, куда передаем id записи, или, что-то еще, не важно, и в этом экшене находим нужную нам запись, и в виде модели рендерим в представление, которое нам собственно и возвращается. А тут как быть, если нужно не на другую страницу переходить, а просто выводить форму редактирования в модальном окне на той же странице? По сути я хочу, чтобы при нажатии на кнопку редактирования, открывалось модальное окно с формой редактирования этой записи.
Во вложении, есть два скрина. На первом общий вид виджета уже вставленного в представление /profile/update, а на втором модальное окошко для создания сертификата. Модальное окошко для создания и кнопка "Добавить сертификат" рендерится сразу виджетом. В виджете в методе run просто передается в представление модель Certificate. Действия создания и удаления, как и советовали вынес в отдельный контроллер.
Скриншот1:
https://cloud.mail.ru/public/HcwY/Qni66ShvA
Скриншот2:
https://cloud.mail.ru/public/9ZLc/gC4TEfNQ5
Остался один вопрос нерешенным. Так как виджет выводит в другом представлении (в редактировании профиля) поля другой модели, я их решил красиво в модальное окно засунуть. Получается идут поля из другой модели, потом кнопка "Добавить сертификаты" и под ней выводится список уже созданных сертификатов в виде картинок и у каждого сертификата есть своя панелька с кнопками (редактировать, удалитьть, увеличить). С удалением, увеличением и созданием проблем нет. А вот с редактированием пока не понимаю, как сделать.
Обычно при редактировании, мы вызываем какой-то экшен, куда передаем 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: Пару вопросов про виджеты
Стоп. Что-то я туплю похоже. Обычным же ajax запросом можно сделать вроде. Сегодня попробую, отпишусь)
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
Да, оказалось не сложно. Нужно просто к кнопке редактирования (которая должна открывать модальное окно с формой редактирования), добавить, например data атрибут (data-certificate-id), по клику по этой ссылке, брать значение этого атрибута и передавать пост запросом через аякс в нужный экшен, там находить нужную модель, рендерить ее в представление, как положенно и потом среди ответа в функции success, в ajax, методом find искать нужну. часть и подставлять в модальное окно.
Пока только небольшой баг остался. При вставке контента ajax запросом, картинка в preview не отображается почему-то, а поле dropzone растягивается на пол страницы. Для загрузки картинок пользуюсь плагином krajee FileInput.
Пока только небольшой баг остался. При вставке контента ajax запросом, картинка в preview не отображается почему-то, а поле dropzone растягивается на пол страницы. Для загрузки картинок пользуюсь плагином krajee FileInput.
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
Что-то я погорячился с простотой этой затеи) При загрузке контента ajax, получается, что все плагины не работают. У меня в форме, которую я аяксом вставляю в модальное окно, подключены плагины - datepiker и fileinput. После подгрузки этой формы в модальное окно, плагины не пашут, так как подгруженная аяксом структура формы, для подгруженных ранее скриптов и стилей типа еще не существует. И даже если повторно тупо подгружать скрипты в аяксе, находя их на странице через append, все равно не получается.
Как тут можно быть? Или может вся затея с аяксом не подходит?
Сейчас принцип такой -
На странице есть заранее подготовленное модальное окно. При нажатии на кнопку редактирования, аяксом отправляется пост запрос к экшену certificates/update/57, где 57 собственно номер сертификата. В ответе, в функции success мы получаем то что нам возвращает функция рендера, в методе update. В этом ответе я нахожу форму и вставляю ее в тело модального окна.
Как тут можно быть? Или может вся затея с аяксом не подходит?
Сейчас принцип такой -
На странице есть заранее подготовленное модальное окно. При нажатии на кнопку редактирования, аяксом отправляется пост запрос к экшену certificates/update/57, где 57 собственно номер сертификата. В ответе, в функции success мы получаем то что нам возвращает функция рендера, в методе update. В этом ответе я нахожу форму и вставляю ее в тело модального окна.
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
Честно говоря, толкового решения проблемы я так и не нашел. Решил пока повторной загрузкой стилей и скриптов через тот же ajax, но это бед практик. Раньше я уже решал подобную проблему, но там было проще, я обработчик вешал то ли по клику на родительский элемент, то ли по первому наведению, а не при загрузке документа.
Что-то мне подсказывает, что пора изобретать какой-то автозагрузчик js, а то проблема со скриптами в контенте загруженном ajax уже не нова)
Что-то мне подсказывает, что пора изобретать какой-то автозагрузчик js, а то проблема со скриптами в контенте загруженном ajax уже не нова)
-
- Сообщения: 104
- Зарегистрирован: 2015.10.04, 09:47
Re: Пару вопросов про виджеты
Иницируйте плагины после создания (показа) содержимого модального окна. Можно повесить на келлбек ajax )Sereja3578 писал(а):- datepiker и fileinput.
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
Возможно это действительно более правильный вариант, так как вроде не нужно второй раз грузить скрипты. Правда, придется тогда разбирать ответ, для каждой его нужной части инициализировать нужные плагины, а потом все склеивать и отправлять) Но по сути это лучше чем грузить кучу скриптов заново.alexnew2000 писал(а):Иницируйте плагины после создания (показа) содержимого модального окна. Можно повесить на келлбек ajax )Sereja3578 писал(а):- datepiker и fileinput.
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
Вот за это спасибо) Я не знал, что есть такая полезная фишка. Точнее знал, что есть, но как работает не знал.rak писал(а):да есть же renderAjax, в чем проблема?
Вчера в конечном итоге сделал то же самое, по сути, что делает этот метод, но сам. Взял ответ и, в функции success перед вставкой, убрал все лишнее от шаблона, оставил только нужную часть, плюс скрипты и стили.
Но опять же, это все та же повторная загрузка пачки скриптов.
В предыдущем коменте посоветовали инициализировать нужные аплагины перед вставкой ajax контента. О минусах тоже упомянул.
-
- Сообщения: 104
- Зарегистрирован: 2015.10.04, 09:47
Re: Пару вопросов про виджеты
Извините, но не перед вставкой ajax контента, а после вставки контента.Sereja3578 писал(а):....
В предыдущем коменте посоветовали инициализировать нужные аплагины перед вставкой ajax контента. ...
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
Это я не правильно написал, я имел ввиду после вставки, как вы и сказали на колбеке, например на complete.alexnew2000 писал(а):Извините, но не перед вставкой ajax контента, а после вставки контента.Sereja3578 писал(а):....
В предыдущем коменте посоветовали инициализировать нужные аплагины перед вставкой ajax контента. ...
-
- Сообщения: 977
- Зарегистрирован: 2014.08.27, 21:54
Re: Пару вопросов про виджеты
Да, через renderAjax надо.
Работал в свое время с модальными окнами. Написал более менее стабильный виджет.
https://github.com/loveorigami/yii2-modal-ajax
Использую во всех своих админках (в гриде, во формах при добавлении нового элемента в селект, если таковой не присутсвует, формы настроек под каждый модуль, подгрузить форму или данные из action и т.п.).
Работал в свое время с модальными окнами. Написал более менее стабильный виджет.
https://github.com/loveorigami/yii2-modal-ajax
Использую во всех своих админках (в гриде, во формах при добавлении нового элемента в селект, если таковой не присутсвует, формы настроек под каждый модуль, подгрузить форму или данные из action и т.п.).
- Sereja3578
- Сообщения: 204
- Зарегистрирован: 2016.09.21, 11:15
- Контактная информация:
Re: Пару вопросов про виджеты
В общем всем спасибо за ценные советы)
Пришел к такому выводу:
1. Если не хотите повторно грузить скрипты на страницу, то используйте метод, который посоветовал alexnew2000:
В ajax, после вставки на страницу контента, в колбеке, напривер в complete, просто заново инициализируйте плагины. В некоторых местах понадобятся дополнительные телодвижения, чтобы настроить эти плагины, например для плагина загрузки картинок, чтобы превью выводить, нужно в js передать название картинки, потом сформировать саму картинку и указать, как оьычно в настройках плагина. Но зато такой способ не замедляет работу скрипта.
2. Если скорость не особо важна, то можно сделать как посоветовал rak и, воспользоваться в контроллере методом renderAjax, и просто вставлять целиком весь ответ ajax куда нужно, при этом все скрипты будут повторно загружены.
Пришел к такому выводу:
1. Если не хотите повторно грузить скрипты на страницу, то используйте метод, который посоветовал alexnew2000:
В ajax, после вставки на страницу контента, в колбеке, напривер в complete, просто заново инициализируйте плагины. В некоторых местах понадобятся дополнительные телодвижения, чтобы настроить эти плагины, например для плагина загрузки картинок, чтобы превью выводить, нужно в js передать название картинки, потом сформировать саму картинку и указать, как оьычно в настройках плагина. Но зато такой способ не замедляет работу скрипта.
2. Если скорость не особо важна, то можно сделать как посоветовал rak и, воспользоваться в контроллере методом renderAjax, и просто вставлять целиком весь ответ ajax куда нужно, при этом все скрипты будут повторно загружены.
Re: Пару вопросов про виджеты
Они не будут повторно загружены, браузер кеширует.Sereja3578 писал(а): 2. Если скорость не особо важна, то можно сделать как посоветовал rak и, воспользоваться в контроллере методом renderAjax, и просто вставлять целиком весь ответ ajax куда нужно, при этом все скрипты будут повторно загружены.
Yii2 universal module sceleton - for basic and advanced templates