26 июл. 2019 г.
Всем привет! Сегодня речь пойдет о Yii2, а конкретно о Detail View Widget. Этот widget позволяет выводить информацию на странице. В общем-то все, кто работал с Yii наверняка о нем знают. Чаще всего виджет используется в разных админках и т.д.
В этой заметке хочу описать некоторые довольно простые идеи по организации кода Detail view. Документация по Detail View. В коде выглядит примерно так:
<?= echo DetailView::widget([ 'model' => $model, 'attributes' => [ 'title', // title attribute (in plain text) 'description:html', // description attribute in HTML [ // the owner name of the model 'label' => 'Owner', 'value' => $model->owner->name, ], 'created_at:datetime', // creation date formatted as datetime ], ]); ?>
При этом довольно часто нужно вывести не просто значение атрибута, а кнопку, атрибут связанной сущности, или что-нибудь не совсем обычное. Также, возможно, что нам нужно вывести такое значение в нескольких DetailView. В результате получаем, например, такой код, повторяющийся в разных view:
<?= DetailView::widget([ 'model' => $client, 'attributes' => [ [ 'label' => $client->clientMobileApp->getAttributeLabel('link_ios'), 'value' => $client->clientMobileApp->link_ios ] ], ]) ?>
В этом случае хотелось бы инкапсулировать и вынести в отдельный класс повторяющийся код.
Для этого добавим класс components/detailView/attributes/ModelAttribute
,
получающий на вход модель и название атрибута, возвращающий массив для отображения в DetailView.
В Detail View Widget используются массивы вывода атрибутов. Соответственно, наш атрибут тоже на выходе должен представлять собой массив.
Класс ModelAttribute имеет один публичный метод toArray
. Также имеет смысл добавить интерфейс AttributeInterface
.
<?= DetailView::widget([ 'model' => $client, 'attributes' => [ (new ModelAttribute($client->clientMobileApp, 'link_ios'))->toArray(), ], ]) ?>
<?php namespace app\components\detailView\attributes; use yii\base\Model; /** * Class ModelAppAttribute * @package app\modules\admin\components\detailView\attributes */ class ModelAttribute implements AttributeInterface { private $model; private $attribute; private $format; /** * ModelAttribute constructor. * @param Model $model * @param $attribute * @param string $format */ public function __construct(Model $model, $attribute, $format = 'text') { $this->model = $model; $this->attribute = $attribute; $this->format = $format; } /** * @param array $fields * @param array $expand * @param bool $recursive * @return array */ public function toArray(array $fields = [], array $expand = [], $recursive = true) { $attribute = $this->attribute; return [ 'label' => $this->model->getAttributeLabel($attribute), 'value' => $this->model->$attribute, 'format' => $this->format ]; } }
<?php namespace app\components\detailView\attributes; /** * Interface AttributeInterface * @package app\modules\admin\components\detailView\attributes */ interface AttributeInterface { /** * @return mixed */ public function toArray(); }
ModelAttribute здесь взят лишь для примера. Кастомный атрибут можно использовать и для других целей. Например, для вывода графика, вывода кнопок, отображения списка файлов, более наглядного отображения чекбоксов(Yes/No), отображения списка связанных сущностей, подключения html шаблонов и др. В конечном итоге, делает Detail View Widget менее перегруженным и более упрядоченным.
На этом пока все, спасибо за внимание!