Виджет Или Не Виджет

всем привет

хочу задать вопрос теоретического характера на тему - как правильнее поступить

суть = в сайдбаре выводится набор функциональных элементов:

  • ссылки

  • форма поиска

  • баннер по запросу к БД

  • последние акции и т.д.

есть вариативность с той точки зрения, что на разных страницах компоновка этих элементов будет разная

вопрос: как всю эту бодягу лучше организовать? простые ссылки - с ними все ясно, а вот то что требует обращения к БД - это правильнее сделать виджетом или как?

ведь явно прослеживается обращение к базе и если в одном подключаемом файле сделать и запрос и вывод - то как-то это "не хорошо"

хэлп ми плиз!

Что тут плохого?

В вьюхе не надо обращаться к базе, но можно это делать в контроллере (ApplicationController - от которого наследуются все остальные контроллеры), есть же всякие before и after фильтры.

на мой взгляд вы правы ведь виджеты специально для этого и созданы чтоб дополнять основные данные на странице!!!

по поводу выноса в контроллер не совсем верно потому что никогда не знаешь где будешь эти данные использовать а виджет прекрасно встроится в любое место шаблона!

то есть использовать виджет как уменьшенную копию контроллера?

ну там - получить данные из модели, обработать и подать в рендер

так?

По сути, виджет и есть уменьшенная копия контроллера )

Если прямо совсем-совсем напрягает - можете применить CClipWidget, контент в который набивать из "взрослого" контроллера (например, из базового components/Controller).

Но, в целом, виджеты для таких целей отлично работают.

да нет… клип-виджет не получится - ибо речь идет о сквозном подключении функционала на сайте в сайдбаре…

тогда у меня вот еще какой вопрос: метод init вызывается в момент инициализации объекта виджета, а run - во время выполнения

так внутри кого из них лучше обращаться к БД?

в случае вывода баннера из БД получилось вот что =


class WidgetBanner extends CWidget {

    

    public function run()

    {    

        $crit = new CDbCriteria();

        $crit->condition = "`show` = 'yes'";

        $crit->order = "id_ban DESC";

        

        $data = Banners::model()->find($crit);

        

        $this->render('widgetBanner',array(

            'data'=>$data,

        ));

    }

    

}

так удобнее и правильно


class WidgetBanner extends CWidget {

    public $count = 1;

    public $template = 'widgetBanner';

    public function run()

    {    

        $crit = new CDbCriteria();

        $crit->condition = "`show` = 'yes'";

        $crit->order = "id_ban DESC";

		$crit->limit = $this->count;

		

		$dataProvider=new CActiveDataProvider('Banners', array(

			'criteria'=> $crit,    

			'pagination'=>false

		));

      

        $this->render($this->template,array(

            'dataProvider'=>$dataProvider,

        ));

    }    

}

а в представлении виджета использовать zii.widgets.CListView в котором еще предусматривать файл itemView ?

не громоздковато с датаПровайдером?

это не обязательно использовать можно просто




foreach($dataProvider->getData() as $banner){

/*вывод баннера*/

}



с дата провайдером преимущество в кэшировании!




if($this->beginCache('mybanners', array('duration'=>3600))) {

foreach($dataProvider->getData() as $banner){

/*вывод баннера*/

}

$this->endCache(); }



теперь запрос к базе будет совершатся раз в час

ооооооо! про кэширование - это супер-пупер!

спасибище!