Используйте виджет в статически вызываемом методе
Обычно виджет используется при вызове CController::widget()
на примере CController
как правило, $this
в представлении.
Но если я пишу статический метод, скажем, помощник, то у меня нет доступа к экземпляру CController
, Так как мне использовать виджет?
Скажем далее, что этот вспомогательный метод вызывается в eval()
'выражение в CDataColumn
"s value
имущество. Это плохое выражение почти не имеет контекста. Как помощник должен использовать виджет?
РЕДАКТИРОВАТЬ: Пример кода
Как и просили, посмотреть пример:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(),
'columns' => array(
array(
'name' => 'attrName',
'value' => '--USE WIDGET HERE--',
),
)
));
3 ответа
Этот ответ не отвечает на вопрос в целом, но в конкретном случае - как получить доступ к контроллеру и использовать виджет в контексте оцененного выражения CDataColumn::$value
Вы можете использовать это:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(),
'columns' => array(
array(
'name' => 'attrName',
'value' => function ($data, $row, $column) {
$controller = $column->grid->owner;
$controller->widget(/* ... etc ... */);
},
),
)
));
Хитрость заключалась в том, что CDataColumn::renderDataCellContent()
использования CComponent::evaluateExpression()
, который вставляет экземпляр компонента в обратный вызов в качестве последнего параметра. В этом случае этот компонент является CDataColumn
, который ссылается на контроллер, как показано.
Я не люблю писать выражения PHP как строковые литералы, поэтому я рад найти эту опцию.
Комментарий к http://www.yiiframework.com/doc/api/1.1/CDataColumn показывает нам другой способ использования виджета в значении столбца, который я не пробовал.
Это рабочее решение для вызова виджетов в статических методах в Yii.
Yii::app()->controller->widget('widget');
Нет прямого способа вызвать виджет из контроллера, потому что вы не должны этого делать. Это все о MVC. Виджеты нужны и / или полезны только в представлениях, а доступ к представлениям осуществляется только через контроллеры. Это теория.
Я полагаю, вы ошиблись. Правильный, MVC-дружественный способ сделать то, что вы пытаетесь сделать, заключается в использовании renderPartial(). Вы знаете: у вас есть определенный контент, и вы хотите украсить его (в вашем случае вы хотите впитать его внутри виджета, верно?) Перед его отображением конечному пользователю; Итак, из представления вы вызываете renderPartial(). Он отправит ваши данные в файл, где будет правильно оформлен. renderPartial() возвращает контент, правильно отформатированный, и теперь вы можете отобразить его в виде.
К сожалению, в вашем конкретном случае вы работаете с сеткой (верно?), И, по крайней мере, с моей точки зрения, это немного усложняет ситуацию. Чтобы украсить содержимое для элемента CGridColumn-subclass (например, CDataColumn), вам необходимо переопределить метод renderDataCellContent(). Проверьте это здесь: http://www.yiiframework.com/doc/api/1.1/CDataColumn