yii2-如何自定義小物件/佈局獲取動態數據

(注:此爲yii2高級應用)
需求:在佈局中如何動態讀取數據表中數據?而且具備全局性(即數據在全站均可有效)?
如上:除了使用session外,還有一種比較好的方式就是使用小部件。php

帶着問題進入事例:

在建立一個項目的後臺,我把菜單導航欄寫進數據表,全部菜單導航欄是經過數據表來控制的。那麼,在佈局中如何把菜單讀出來呢?以下圖
圖片描述web

若是使用控制器來渲染,菜單欄是不具備全局性。
這時,不部件是一個好的方案!不只解決了讀取數據表中的數據,還保證了菜單欄的全局性。bootstrap

1、建立數據表 nav(菜單),並使用gii建立model

此表用來保存全部菜單數據。此步很簡單,在此略過!
每一個人的方式不同,此例主要是講解如何使用小物件。yii2

2、建立小部件

在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();

3、建立佈局文件並使用剛建立的小部件

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 = '';
        }
       //......
    }
}
相關文章
相關標籤/搜索