Тема Yii dataProvider main.php

В моем SiteController.php

public function actionIndex()
{
    // renders the view file 'protected/views/site/index.php'
    // using the default layout 'protected/views/layouts/main.php'
    //$this->render('index');

    $dataProviderUser=new CActiveDataProvider('User',array(
                'pagination'=>array(
                    'pageSize'=>20,
                ),
            ));
    $dataProviderDomain = new CActiveDataProvider('Domain');

    $this->render('index',array(
    'dataProvider1'=>$dataProviderUser,
    'dataProvider2'=>$dataProviderDomain
    ));
}

В моих темах/k/views/layout/main.php

        <?php 
        if(!Yii::app()->user->isGuest)
        {
        $this->widget('zii.widgets.CListView', array(
            'dataProvider'=>$dataProvider2,
            'itemView'=>'_view',));
        ?>

Появляется эта ошибка: Неопределенная переменная: dataProvider2

Если я сделаю это в своем main.php:

<?php 
        $dataProvider2 = new CActiveDataProvider('Domain');
        if(!Yii::app()->user->isGuest)
        {
        $this->widget('zii.widgets.CListView', array(
            'dataProvider'=>$dataProvider2,
            'itemView'=>'_view',));
        ?>

Это работает нормально до сих пор. Но если я перейду к профилю пользователя:

/user/view/id/5

Свойство "Domain.username" не определено.

Таким образом, в моем пользователе _view.php Yii, похоже, использует поставщика данных домена.

Как мне вставить эти dataProviders в мой файл макета main.php? Похоже, что SiteController.php делает это неправильно.

Было бы очень хорошо, если бы у кого-то есть идея здесь. Заранее спасибо.


person K213    schedule 09.12.2013    source источник
comment
возможный дубликат Как передать переменные в макет?   -  person soju    schedule 09.12.2013
comment
попробовал это. Это не работает.   -  person K213    schedule 09.12.2013


Ответы (1)


Переменные, которые вы определили в своем действии контроллера, доступны только для файлов непосредственного представления, которые используются для визуализации представления. Они недоступны для макетов. Однако макеты смогут использовать общедоступные методы и свойства контроллера. Итак, если вы хотите передать переменную в свой макет, вам нужно объявить ее как свойство контроллера. Есть два способа сделать это.

Во-первых, вы можете просто создать общедоступную переменную.

Class YourController extends CController{

public $dataProvider2;

public function actionIndex(){
// renders the view file 'protected/views/site/index.php'
    // using the default layout 'protected/views/layouts/main.php'
    //$this->render('index');

    $dataProviderUser=new CActiveDataProvider('User',array(
                'pagination'=>array(
                    'pageSize'=>20,
                ),
            ));
    $dataProviderDomain = new CActiveDataProvider('Domain');

//Added new line here
$this->dataProvider2 = $dataProviderDomain;
    $this->render('index',array(
    'dataProvider1'=>$dataProviderUser,
    'dataProvider2'=>$dataProviderDomain
    ));
}

}

$this->dataProvider теперь доступен в вашем файле представления, но не забудьте проверить его существование перед его использованием.

Другой метод — использовать магический метод получения из Yii.

В вашей модели опишите такой метод;

public function getdataProvider2(){
return $this->_dataProvider2;
}

и вам понадобится недвижимость;

private $_dataProvider2;
person Joe Miller    schedule 09.12.2013
comment
Привет, спасибо за решение. Теперь он работает с $this-›dataProvider2 в файле main.php. Но если я нажму «Профиль пользователя», он скажет мне, что dataProvider2 пуст. Мне также пришлось добавить dataProvider2 в мой UserController. Таким образом, кажется, что все эти контроллеры используют одну и ту же переменную, но по-разному. Я действительно не понимаю. - person K213; 09.12.2013
comment
Это вопрос контекста. Когда вы находитесь в макете, $this относится к контроллеру, вызывающему макет. Таким образом, если $this-›dataProvider2 не определен в этом контроллере, макет не сможет получить к нему доступ. - person Joe Miller; 09.12.2013
comment
Итак, могу ли я сделать что-то вроде DomainController.dataProvider2, чтобы он всегда принимал правильный контроллер? - person K213; 09.12.2013
comment
Я не совсем понимаю, что ты имеешь в виду, @Konter. Когда вы находитесь в файле представления или файле макета, есть только один контроллер, обрабатывающий этот файл. Вы не можете ссылаться на свойство другого контроллера, если это то, что вы имеете в виду. Если dataProvider1 и dataProvider2 будут переменными, которые будут использоваться во всех ваших контроллерах, вам может быть лучше создать класс, который расширяет CController и предоставляет эти переменные, а затем ваши другие контроллеры расширят этот класс. - person Joe Miller; 09.12.2013