Используйте виджет в статически вызываемом методе

Обычно виджет используется при вызове 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

Другие вопросы по тегам