YII2 получение данных из БД в widget?

Здравствуйте.
Для вывода и отображения данных из БД в layouts main.php как я понял нужно использовать widget.
Вот самый простой пример создания widget:
Новый виджет
namespace app\components;

use yii\base\Widget;
use yii\helpers\Html;

class NewsWidget extends Widget
{
    public $message;

    public function init(){
        parent::init();
        if ($this->message === null){
            $this->message = 'News today';
        }
    }

    public function run(){
        return Html::encode($this->message);
    }
}

Отображение виджета:
NewsWidget::widget(['message' => 'Good day']);
С этим всё понятно. А вот получить и вывести данные из БД?
Где писать запрос( init? )? Как правильно передать полученные данные (return или render) ? Как вывести данные в layouts?
Заранее спасибо.
  • Вопрос задан
  • 3215 просмотров
Пригласить эксперта
Ответы на вопрос 3
R0dger
@R0dger
Laravel/Yii/2 AngularJs PHP RESTful API
Что то странное... я бы на Вашем месте сделал чуть по другому... в layout выводил бы закешированные новости.. ну а кеш стройте как уже хочется... хотите после записи, хотите по времени и т.д.
имхо если Новости постоянно на всех страницах.. имхо лучше закешировать и выводить, тем более это не очень критическая информация..
Ответ написан
Комментировать
@link_irk
Используйте модели. Виджеты так же могут рендерить view.
...
    public function run()
    {
        $model = News::find() -> limit(10) -> all();
        return $this -> render('news', ['news' => $model);
    }
...


В layout'е делайте вызов виджета
<?php echo NewsWidget::widget(); ?>
Ответ написан
@matperez
В виджетах лучше не получать данные вовсе, ни через модели, ни через прямое обращение к базе. Передавайте туда чистые данные как это например сделано с хлебными крошками или на крайняк какой-нибудь DataProvider так же скрывающий реальный источник данных.
Я бы переопределил класс yii\web\View, добавил бы ему поле news для хранения списка новостей и явно передавал бы его в виджет в шаблоне. Сами данные во View можно подгонять в контроллере или если эти данные нужны везде, можно в самом классе View.
Как-нибудь так:
<?php
class NewsProvider 
{
    public function getNews()
    {
        return News::find()->all();
    }
}

class View extends yii\web\View 
{
    /**
     * @var NewsProvider
     */
    private $newsProvider;

    /**
     * @var array
     */
    private $news;
    
    public function __construct(NewsProvider $newsProvider, array $config = [])
    {
        $this->newsProvider = $newsProvider;
        parent::__construct($config);
    }
    
    public function getNews()
    {
        if (!$this->news) {
            $this->news = $this->newsProvider->getNews();
        }
        return $this->news;
    }
}

echo NewsWidget::widget(['items' => $this->getNews()]);


Класс View нужно создавать собственный. В папку vendor изменения вносить ни при каких условиях нельзя, это не ваш код.

Например можно создать класс app\components\View и подключить его в конфиге (сделать так, что бы Yii использовал именно этот класс для компонента view)
// в файле config/web.php 
  'components' => [
    'view' => 'app\components\web\View',
  ],
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы