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 менее перегруженным и более упрядоченным.
На этом пока все, спасибо за внимание!