(注:此爲yii2高級應用)
需求:在佈局中如何動態讀取數據表中數據?而且具備全局性(即數據在全站均可有效)?
如上:除了使用session外,還有一種比較好的方式就是使用小部件。php
在建立一個項目的後臺,我把菜單導航欄寫進數據表,全部菜單導航欄是經過數據表來控制的。那麼,在佈局中如何把菜單讀出來呢?以下圖web
若是使用控制器來渲染,菜單欄是不具備全局性。
這時,不部件是一個好的方案!不只解決了讀取數據表中的數據,還保證了菜單欄的全局性。bootstrap
此表用來保存全部菜單數據。此步很簡單,在此略過!
每一個人的方式不同,此例主要是講解如何使用小物件。yii2
在backend下建立components/NavWidget.php (高級應用後臺是沒有components的)session
<?php namespace backend\components; use backend\models\Nav; use yii\base\Widget; use yii\helpers\Html; class NavWidget extends Widget { public function run() { //從數據表中讀出數據 $nav = Nav::find() ->where(['status' => 1]) ->orderBy('sort ASC') ->all(); foreach($nav as $_v){ $navs[] = $_v->id.'|'.$_v->nav_cn.'|'.$_v->nav_en; } // 渲染視圖 return $this->render('@app/views/site/_nav', [ 'nav'=>$navs, ]); } } ?>
run()方法是處理和返回數據表中的數據;app
這裏是return了一個_nav.php的視圖文件(具體地址是在backend/views/site/_nav.php),
由於小部件須要渲染不少複雜內容,一種更好的辦法是將內容放入這個視圖文件裏面。
若是內容不多就直接return $nav;yii
若是render不指定一個具體的地址會默認在backend/components/views/xxx.php;佈局
讓咱們看一眼這個小部件渲染的視圖文件 以下:post
use yii\helpers\Html; /* @var $this yii\web\View */ use yii\bootstrap\Nav; NavBar::begin([ 'brandLabel' => '首頁', 'brandUrl' => Yii::$app->homeUrl, 'options' => [ 'class' => 'navbar-inverse navbar-fixed-top', 'id' => 'menu-top', ], //'brandOptions' => ['class' => 'fa fa-flag fa-2x pull-left'], ]); if (Yii::$app->user->isGuest) { $menuItems[] = ['label' => '登錄', 'url' => ['/site/login']]; } else { //循環出菜單欄 if(isset($nav)){ for($n=0;$n<count($nav);$n++){ $_v = explode('|',$nav[$n]); $menuItems[] = [ 'label' => $_v[1], 'url' => ["/$_v[2]/default/index",'id'=>$_v[0],'en'=>$_v[2]], //'linkOptions' => ['class' => 'active'], //'options' => ["id"=>"_M$n"], ]; } } $menuItems[] = [ 'label' => ' Log out', 'url' => ['/site/logout'], 'linkOptions' => ['data-method' => 'post','class'=>'fa fa-sign-out'], ]; } echo Nav::widget([ 'options' => ['class' => 'navbar-nav navbar-right'], 'items' => $menuItems, ]); NavBar::end();
backend/views/layouts/main.php
//使用小部件this
<?= NavWidget::widget() ?>
這樣,小部件裏面的動態數據就出來了,而且全局可以使用。
另外:你若是想把NavWidget小部件裏面有些參數經過get傳到NewWidget這個小部件裏面去(反正我是有這個需求的),可經過下面這種方式
在NavWidget渲染的視圖裏面(這段在上面有) 傳個ID給別的小部件裏面使用
'url' => ["/$_v[2]/default/index",'id'=>$_v[0]],
別的小部件使用處接收下
$id = isset($_GET['id']) ? $_GET['id'] : 1; NewWidget::widget(['id'=>$id])
在NewWidget小部件裏(部分代碼)接收id
namespace backend\components; use yii\base\Widget; use yii\helpers\Html; class NewWidget extends Widget { public $id; //調用處把這個id傳進來了 public function run() { if(isset($this->id)){ $navbar = xxx::find() ->with('xxx') //聯表 ->where(['status' => 1,'nid'=>$this->id])//id就這樣被使用了 ->orderBy('id asc') ->all(); }else{ $navbar = ''; } //...... } }